World pass VK and GL Mipmap load
parent
15f5b090b5
commit
623cbb8724
BIN
resource/content/shaders/Color.fs.spv (Stored with Git LFS)
BIN
resource/content/shaders/Color.fs.spv (Stored with Git LFS)
Binary file not shown.
BIN
resource/content/shaders/Color.vs.spv (Stored with Git LFS)
BIN
resource/content/shaders/Color.vs.spv (Stored with Git LFS)
Binary file not shown.
BIN
resource/content/shaders/Sky.fs.spv (Stored with Git LFS)
BIN
resource/content/shaders/Sky.fs.spv (Stored with Git LFS)
Binary file not shown.
BIN
resource/content/shaders/Sky.vs.spv (Stored with Git LFS)
BIN
resource/content/shaders/Sky.vs.spv (Stored with Git LFS)
Binary file not shown.
BIN
resource/content/shaders/Tris.fs.spv (Stored with Git LFS)
BIN
resource/content/shaders/Tris.fs.spv (Stored with Git LFS)
Binary file not shown.
BIN
resource/content/shaders/Tris.spv (Stored with Git LFS)
BIN
resource/content/shaders/Tris.spv (Stored with Git LFS)
Binary file not shown.
BIN
resource/content/shaders/Tris.vs.spv (Stored with Git LFS)
BIN
resource/content/shaders/Tris.vs.spv (Stored with Git LFS)
Binary file not shown.
BIN
resource/content/shaders/Voxel.fs.spv (Stored with Git LFS)
BIN
resource/content/shaders/Voxel.fs.spv (Stored with Git LFS)
Binary file not shown.
BIN
resource/content/shaders/Voxel.geo.fs.spv (Stored with Git LFS)
BIN
resource/content/shaders/Voxel.geo.fs.spv (Stored with Git LFS)
Binary file not shown.
BIN
resource/content/shaders/Voxel.geo.gs.spv (Stored with Git LFS)
BIN
resource/content/shaders/Voxel.geo.gs.spv (Stored with Git LFS)
Binary file not shown.
BIN
resource/content/shaders/Voxel.geo.ins.fs.spv (Stored with Git LFS)
BIN
resource/content/shaders/Voxel.geo.ins.fs.spv (Stored with Git LFS)
Binary file not shown.
BIN
resource/content/shaders/Voxel.geo.ins.gs.spv (Stored with Git LFS)
BIN
resource/content/shaders/Voxel.geo.ins.gs.spv (Stored with Git LFS)
Binary file not shown.
BIN
resource/content/shaders/Voxel.geo.ins.vs.spv (Stored with Git LFS)
BIN
resource/content/shaders/Voxel.geo.ins.vs.spv (Stored with Git LFS)
Binary file not shown.
BIN
resource/content/shaders/Voxel.geo.vs.spv (Stored with Git LFS)
BIN
resource/content/shaders/Voxel.geo.vs.spv (Stored with Git LFS)
Binary file not shown.
BIN
resource/content/shaders/Voxel.ins.fs.spv (Stored with Git LFS)
BIN
resource/content/shaders/Voxel.ins.fs.spv (Stored with Git LFS)
Binary file not shown.
BIN
resource/content/shaders/Voxel.ins.vs.spv (Stored with Git LFS)
BIN
resource/content/shaders/Voxel.ins.vs.spv (Stored with Git LFS)
Binary file not shown.
BIN
resource/content/shaders/Voxel.vs.spv (Stored with Git LFS)
BIN
resource/content/shaders/Voxel.vs.spv (Stored with Git LFS)
Binary file not shown.
BIN
resource/content/textures/1024-realistic/sky/Debug.cube.back.dds (Stored with Git LFS)
Normal file
BIN
resource/content/textures/1024-realistic/sky/Debug.cube.back.dds (Stored with Git LFS)
Normal file
Binary file not shown.
BIN
resource/content/textures/1024-realistic/sky/Debug.cube.bottom.dds (Stored with Git LFS)
Normal file
BIN
resource/content/textures/1024-realistic/sky/Debug.cube.bottom.dds (Stored with Git LFS)
Normal file
Binary file not shown.
BIN
resource/content/textures/1024-realistic/sky/Debug.cube.front.dds (Stored with Git LFS)
Normal file
BIN
resource/content/textures/1024-realistic/sky/Debug.cube.front.dds (Stored with Git LFS)
Normal file
Binary file not shown.
BIN
resource/content/textures/1024-realistic/sky/Debug.cube.left.dds (Stored with Git LFS)
Normal file
BIN
resource/content/textures/1024-realistic/sky/Debug.cube.left.dds (Stored with Git LFS)
Normal file
Binary file not shown.
BIN
resource/content/textures/1024-realistic/sky/Debug.cube.right.dds (Stored with Git LFS)
Normal file
BIN
resource/content/textures/1024-realistic/sky/Debug.cube.right.dds (Stored with Git LFS)
Normal file
Binary file not shown.
BIN
resource/content/textures/1024-realistic/sky/Debug.cube.top.dds (Stored with Git LFS)
Normal file
BIN
resource/content/textures/1024-realistic/sky/Debug.cube.top.dds (Stored with Git LFS)
Normal file
Binary file not shown.
BIN
resource/content/textures/1024-realistic/sky/Space_orange.cube.back.dds (Stored with Git LFS)
BIN
resource/content/textures/1024-realistic/sky/Space_orange.cube.back.dds (Stored with Git LFS)
Binary file not shown.
BIN
resource/content/textures/1024-realistic/sky/Space_orange.cube.bottom.dds (Stored with Git LFS)
BIN
resource/content/textures/1024-realistic/sky/Space_orange.cube.bottom.dds (Stored with Git LFS)
Binary file not shown.
BIN
resource/content/textures/1024-realistic/sky/Space_orange.cube.front.dds (Stored with Git LFS)
BIN
resource/content/textures/1024-realistic/sky/Space_orange.cube.front.dds (Stored with Git LFS)
Binary file not shown.
BIN
resource/content/textures/1024-realistic/sky/Space_orange.cube.left.dds (Stored with Git LFS)
BIN
resource/content/textures/1024-realistic/sky/Space_orange.cube.left.dds (Stored with Git LFS)
Binary file not shown.
BIN
resource/content/textures/1024-realistic/sky/Space_orange.cube.right.dds (Stored with Git LFS)
BIN
resource/content/textures/1024-realistic/sky/Space_orange.cube.right.dds (Stored with Git LFS)
Binary file not shown.
BIN
resource/content/textures/1024-realistic/sky/Space_orange.cube.top.dds (Stored with Git LFS)
BIN
resource/content/textures/1024-realistic/sky/Space_orange.cube.top.dds (Stored with Git LFS)
Binary file not shown.
BIN
resource/content/textures/1024-realistic/sky/Space_tray.cube.back.dds (Stored with Git LFS)
BIN
resource/content/textures/1024-realistic/sky/Space_tray.cube.back.dds (Stored with Git LFS)
Binary file not shown.
BIN
resource/content/textures/1024-realistic/sky/Space_tray.cube.bottom.dds (Stored with Git LFS)
BIN
resource/content/textures/1024-realistic/sky/Space_tray.cube.bottom.dds (Stored with Git LFS)
Binary file not shown.
BIN
resource/content/textures/1024-realistic/sky/Space_tray.cube.front.dds (Stored with Git LFS)
BIN
resource/content/textures/1024-realistic/sky/Space_tray.cube.front.dds (Stored with Git LFS)
Binary file not shown.
BIN
resource/content/textures/1024-realistic/sky/Space_tray.cube.left.dds (Stored with Git LFS)
BIN
resource/content/textures/1024-realistic/sky/Space_tray.cube.left.dds (Stored with Git LFS)
Binary file not shown.
BIN
resource/content/textures/1024-realistic/sky/Space_tray.cube.right.dds (Stored with Git LFS)
BIN
resource/content/textures/1024-realistic/sky/Space_tray.cube.right.dds (Stored with Git LFS)
Binary file not shown.
BIN
resource/content/textures/1024-realistic/sky/Space_tray.cube.top.dds (Stored with Git LFS)
BIN
resource/content/textures/1024-realistic/sky/Space_tray.cube.top.dds (Stored with Git LFS)
Binary file not shown.
BIN
resource/content/textures/1024-realistic/terrain/Alien.hos.dds (Stored with Git LFS)
BIN
resource/content/textures/1024-realistic/terrain/Alien.hos.dds (Stored with Git LFS)
Binary file not shown.
BIN
resource/content/textures/1024-realistic/terrain/Alien.nrm.dds (Stored with Git LFS)
BIN
resource/content/textures/1024-realistic/terrain/Alien.nrm.dds (Stored with Git LFS)
Binary file not shown.
BIN
resource/content/textures/1024-realistic/terrain/Dirt.dds (Stored with Git LFS)
BIN
resource/content/textures/1024-realistic/terrain/Dirt.dds (Stored with Git LFS)
Binary file not shown.
BIN
resource/content/textures/1024-realistic/terrain/Dirt.hos.dds (Stored with Git LFS)
BIN
resource/content/textures/1024-realistic/terrain/Dirt.hos.dds (Stored with Git LFS)
Binary file not shown.
BIN
resource/content/textures/1024-realistic/terrain/Dirt.nrm.dds (Stored with Git LFS)
BIN
resource/content/textures/1024-realistic/terrain/Dirt.nrm.dds (Stored with Git LFS)
Binary file not shown.
BIN
resource/content/textures/1024-realistic/terrain/Forest_grass.dds (Stored with Git LFS)
BIN
resource/content/textures/1024-realistic/terrain/Forest_grass.dds (Stored with Git LFS)
Binary file not shown.
BIN
resource/content/textures/1024-realistic/terrain/Forest_grass.hos.dds (Stored with Git LFS)
BIN
resource/content/textures/1024-realistic/terrain/Forest_grass.hos.dds (Stored with Git LFS)
Binary file not shown.
BIN
resource/content/textures/1024-realistic/terrain/Forest_grass.nrm.dds (Stored with Git LFS)
BIN
resource/content/textures/1024-realistic/terrain/Forest_grass.nrm.dds (Stored with Git LFS)
Binary file not shown.
BIN
resource/content/textures/1024-realistic/terrain/Grass.dds (Stored with Git LFS)
BIN
resource/content/textures/1024-realistic/terrain/Grass.dds (Stored with Git LFS)
Binary file not shown.
BIN
resource/content/textures/1024-realistic/terrain/Grass.hos.dds (Stored with Git LFS)
BIN
resource/content/textures/1024-realistic/terrain/Grass.hos.dds (Stored with Git LFS)
Binary file not shown.
BIN
resource/content/textures/1024-realistic/terrain/Grass.nrm.dds (Stored with Git LFS)
BIN
resource/content/textures/1024-realistic/terrain/Grass.nrm.dds (Stored with Git LFS)
Binary file not shown.
BIN
resource/content/textures/1024-realistic/terrain/Mapl.dds (Stored with Git LFS)
BIN
resource/content/textures/1024-realistic/terrain/Mapl.dds (Stored with Git LFS)
Binary file not shown.
BIN
resource/content/textures/1024-realistic/terrain/Mapl.hos.dds (Stored with Git LFS)
BIN
resource/content/textures/1024-realistic/terrain/Mapl.hos.dds (Stored with Git LFS)
Binary file not shown.
BIN
resource/content/textures/1024-realistic/terrain/Mapl.nrm.dds (Stored with Git LFS)
BIN
resource/content/textures/1024-realistic/terrain/Mapl.nrm.dds (Stored with Git LFS)
Binary file not shown.
BIN
resource/content/textures/1024-realistic/terrain/Plain_grass.dds (Stored with Git LFS)
BIN
resource/content/textures/1024-realistic/terrain/Plain_grass.dds (Stored with Git LFS)
Binary file not shown.
BIN
resource/content/textures/1024-realistic/terrain/Plain_grass.hos.dds (Stored with Git LFS)
BIN
resource/content/textures/1024-realistic/terrain/Plain_grass.hos.dds (Stored with Git LFS)
Binary file not shown.
BIN
resource/content/textures/1024-realistic/terrain/Plain_grass.nrm.dds (Stored with Git LFS)
BIN
resource/content/textures/1024-realistic/terrain/Plain_grass.nrm.dds (Stored with Git LFS)
Binary file not shown.
BIN
resource/content/textures/1024-realistic/terrain/Rough_rock.dds (Stored with Git LFS)
BIN
resource/content/textures/1024-realistic/terrain/Rough_rock.dds (Stored with Git LFS)
Binary file not shown.
BIN
resource/content/textures/1024-realistic/terrain/Rough_rock.hos.dds (Stored with Git LFS)
BIN
resource/content/textures/1024-realistic/terrain/Rough_rock.hos.dds (Stored with Git LFS)
Binary file not shown.
BIN
resource/content/textures/1024-realistic/terrain/Rough_rock.nrm.dds (Stored with Git LFS)
BIN
resource/content/textures/1024-realistic/terrain/Rough_rock.nrm.dds (Stored with Git LFS)
Binary file not shown.
BIN
resource/content/textures/1024-realistic/terrain/Sand.dds (Stored with Git LFS)
BIN
resource/content/textures/1024-realistic/terrain/Sand.dds (Stored with Git LFS)
Binary file not shown.
BIN
resource/content/textures/1024-realistic/terrain/Sand.hos.dds (Stored with Git LFS)
BIN
resource/content/textures/1024-realistic/terrain/Sand.hos.dds (Stored with Git LFS)
Binary file not shown.
BIN
resource/content/textures/1024-realistic/terrain/Sand.nrm.dds (Stored with Git LFS)
BIN
resource/content/textures/1024-realistic/terrain/Sand.nrm.dds (Stored with Git LFS)
Binary file not shown.
BIN
resource/content/textures/1024-realistic/terrain/Seaside_rock.hos.dds (Stored with Git LFS)
BIN
resource/content/textures/1024-realistic/terrain/Seaside_rock.hos.dds (Stored with Git LFS)
Binary file not shown.
BIN
resource/content/textures/1024-realistic/terrain/Stone_path.dds (Stored with Git LFS)
BIN
resource/content/textures/1024-realistic/terrain/Stone_path.dds (Stored with Git LFS)
Binary file not shown.
BIN
resource/content/textures/1024-realistic/terrain/Stone_path.hos.dds (Stored with Git LFS)
BIN
resource/content/textures/1024-realistic/terrain/Stone_path.hos.dds (Stored with Git LFS)
Binary file not shown.
BIN
resource/content/textures/1024-realistic/terrain/Stone_path.nrm.dds (Stored with Git LFS)
BIN
resource/content/textures/1024-realistic/terrain/Stone_path.nrm.dds (Stored with Git LFS)
Binary file not shown.
BIN
resource/content/textures/1024-realistic/terrain/Stone_wall.hos.dds (Stored with Git LFS)
BIN
resource/content/textures/1024-realistic/terrain/Stone_wall.hos.dds (Stored with Git LFS)
Binary file not shown.
BIN
resource/content/textures/1024-realistic/terrain/Stone_wall.nrm.dds (Stored with Git LFS)
BIN
resource/content/textures/1024-realistic/terrain/Stone_wall.nrm.dds (Stored with Git LFS)
Binary file not shown.
BIN
resource/content/textures/1024-realistic/terrain/Water.dds (Stored with Git LFS)
BIN
resource/content/textures/1024-realistic/terrain/Water.dds (Stored with Git LFS)
Binary file not shown.
BIN
resource/content/textures/1024-realistic/terrain/Water.hos.dds (Stored with Git LFS)
BIN
resource/content/textures/1024-realistic/terrain/Water.hos.dds (Stored with Git LFS)
Binary file not shown.
BIN
resource/content/textures/1024-realistic/terrain/Water.nrm.dds (Stored with Git LFS)
BIN
resource/content/textures/1024-realistic/terrain/Water.nrm.dds (Stored with Git LFS)
Binary file not shown.
|
@ -9,4 +9,5 @@ layout(location = 0) out vec4 color;
|
|||
|
||||
void main(){
|
||||
color = texture(Texture, UV);
|
||||
color = pow(color, vec4(2.2)); //TODO: Space brightness option
|
||||
}
|
|
@ -43,7 +43,7 @@ layout (location = 0) in VertexData
|
|||
float Depth;
|
||||
} vs;
|
||||
|
||||
layout(location = 0) out vec3 color;
|
||||
layout(location = 0) out vec4 color;
|
||||
|
||||
vec3 expand(vec3 v) {
|
||||
return (v - 0.5) * 2;
|
||||
|
@ -124,7 +124,7 @@ vec3 getTriTexture(sampler2DArray smpl, vec2 crdx, vec2 crdy, vec2 crdz, vec3 we
|
|||
|
||||
void main() {
|
||||
float texScale = 1. / UNIT_SIZE;
|
||||
vec3 tex, texN, worldNormal, texHOS;
|
||||
vec3 tex, worldNormal, texHOS;
|
||||
|
||||
if(TRIPLANAR) {
|
||||
// Triplanar
|
||||
|
@ -138,7 +138,7 @@ if(TRIPLANAR) {
|
|||
vec2 UVy = vs.Position_modelspace.zx * texScale;
|
||||
vec2 UVz = vs.Position_modelspace.xy * texScale;
|
||||
|
||||
vec3 tex = getTriTexture(TextureAtlas, UVx, UVy, UVz, blendWeights);
|
||||
tex = getTriTexture(TextureAtlas, UVx, UVy, UVz, blendWeights);
|
||||
|
||||
if(PBR) {
|
||||
// Whiteout normal blend
|
||||
|
@ -150,9 +150,9 @@ if(PBR) {
|
|||
texNy = vec3(texNy.xy + vs.FaceNormal_worldspace.xz, abs(texNy.z) * vs.FaceNormal_worldspace.y);
|
||||
texNz = vec3(texNz.xy + vs.FaceNormal_worldspace.xy, abs(texNz.z) * vs.FaceNormal_worldspace.z);
|
||||
// Swizzle tangent normals to match world orientation and triblend
|
||||
vec3 worldNormal = normalize(texNx.zyx * blendWeights.x + texNy.xzy * blendWeights.y +texNz.xyz * blendWeights.z);
|
||||
worldNormal = normalize(texNx.zyx * blendWeights.x + texNy.xzy * blendWeights.y +texNz.xyz * blendWeights.z);
|
||||
|
||||
vec3 texHOS = getTriTexture(HOSAtlas, UVx, UVy, UVz, blendWeights);
|
||||
texHOS = getTriTexture(HOSAtlas, UVx, UVy, UVz, blendWeights);
|
||||
}
|
||||
} else {
|
||||
// Cheap planar
|
||||
|
@ -160,16 +160,16 @@ if(PBR) {
|
|||
vec3 nrm = normalize(pow(blendWeights, vec3(80 / sqrt(UNIT_SIZE))));
|
||||
vec2 UV = (vec2(vs.Position_modelspace.xy * nrm.z) + vec2(vs.Position_modelspace.yz * nrm.x) + vec2(vs.Position_modelspace.zx * nrm.y)) * texScale;
|
||||
|
||||
vec3 tex = getTexture(TextureAtlas, UV).rgb;
|
||||
tex = getTexture(TextureAtlas, UV).rgb;
|
||||
if(PBR) {
|
||||
vec3 texN = expand(getTexture(NormalAtlas, UV).rgb);
|
||||
// Swizzle world normals into tangent space and apply Whiteout blend
|
||||
// Swizzle tangent normals to match world orientation and triblend
|
||||
vec3 worldNormal = normalize(vec3(texN.xy + vs.FaceNormal_worldspace.zy, abs(texN.z) * vs.FaceNormal_worldspace.x).zyx * blendWeights.x +
|
||||
worldNormal = normalize(vec3(texN.xy + vs.FaceNormal_worldspace.zy, abs(texN.z) * vs.FaceNormal_worldspace.x).zyx * blendWeights.x +
|
||||
vec3(texN.xy + vs.FaceNormal_worldspace.xz, abs(texN.z) * vs.FaceNormal_worldspace.y).xzy * blendWeights.y +
|
||||
vec3(texN.xy + vs.FaceNormal_worldspace.xy, abs(texN.z) * vs.FaceNormal_worldspace.z).xyz * blendWeights.z);
|
||||
|
||||
vec3 texHOS = getTexture(HOSAtlas, UV).rgb;
|
||||
texHOS = getTexture(HOSAtlas, UV).rgb;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -213,22 +213,21 @@ if(PBR) {
|
|||
|
||||
// MAYBE: shadow
|
||||
|
||||
color =
|
||||
tex =
|
||||
// Ambient : simulates indirect lighting
|
||||
TextureAmbientColor +
|
||||
// Diffuse : "color" of the object
|
||||
visibility * TextureDiffuseColor * LightColor * LightPower * cosTheta / (distance * distance) +
|
||||
// Specular : reflective highlight, like a mirror
|
||||
visibility * TextureSpecularColor * LightColor * LightPower * pow(cosAlpha,5) / (distance * distance);
|
||||
} else {
|
||||
color = tex;
|
||||
}
|
||||
if(FOG) {
|
||||
float ratio = exp(vs.Depth * 0.69)-1;
|
||||
color = mix(color, pow(UBO.fog.rgb, vec3(2.2)), clamp(ratio, 0, 1));
|
||||
tex = mix(tex, UBO.fog.rgb, clamp(ratio, 0, 1));
|
||||
}
|
||||
color = pow(color, vec3(1.0 / 2.2));
|
||||
if(color.r > 1 || color.g > 1 || color.b > 1) {
|
||||
color = vec3(1, 0, 0); //TODO: bloom
|
||||
}
|
||||
//TODO: check gamma color = pow(color, vec3(1.0 / 2.2));
|
||||
color = vec4(tex, 1);
|
||||
/*if(color.r > 1 || color.g > 1 || color.b > 1) {
|
||||
color = vec4(1, 0, 0, 1); //TODO: bloom
|
||||
}*/
|
||||
}
|
|
@ -33,13 +33,15 @@ layout (location = 0) out GeometryData {
|
|||
} gs;
|
||||
|
||||
void main() {
|
||||
for(int j = 0; j < 3; j++) {
|
||||
gs.Textures[j] = vs_in[j].Texture;
|
||||
}
|
||||
for(int i = 0; i < gl_in.length(); i++) {
|
||||
|
||||
gl_Position = gl_in[i].gl_Position;
|
||||
gs.Position_modelspace = vs_in[i].Position_modelspace;
|
||||
gs.FaceNormal_modelspace = vs_in[i].FaceNormal_modelspace;
|
||||
|
||||
gs.Textures[i] = vs_in[i].Texture;
|
||||
switch(int(mod(i,3))) {
|
||||
case 0:
|
||||
gs.TextureRatio = vec3(1,0,0);
|
||||
|
@ -60,9 +62,6 @@ if(PBR) {
|
|||
gs.EyeDirection_cameraspace = vs_in[i].EyeDirection_cameraspace;
|
||||
gs.LightDirection_cameraspace = vs_in[i].LightDirection_cameraspace;
|
||||
}
|
||||
#ifdef SHADOW
|
||||
gs.ShadowCoord = vs_in[i].ShadowCoord;
|
||||
#endif
|
||||
if(FOG) {
|
||||
gs.Depth = vs_in[i].Depth;
|
||||
}
|
||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -37,6 +37,12 @@ Stone_Wall_008_NORM.jpg terrain/Stone_wall.nrm.dds
|
|||
Water_002_COLOR.jpg terrain/Water.dds
|
||||
Water_002_HOS.jpg terrain/Water.hos.dds
|
||||
Water_002_NORM.jpg terrain/Water.nrm.dds
|
||||
Debug.cube.back.png sky/Debug.cube.back.dds
|
||||
Debug.cube.bottom.png sky/Debug.cube.bottom.dds
|
||||
Debug.cube.front.png sky/Debug.cube.front.dds
|
||||
Debug.cube.left.png sky/Debug.cube.left.dds
|
||||
Debug.cube.right.png sky/Debug.cube.right.dds
|
||||
Debug.cube.top.png sky/Debug.cube.top.dds
|
||||
Space_orange.cube.back.png sky/Space_orange.cube.back.dds
|
||||
Space_orange.cube.bottom.png sky/Space_orange.cube.bottom.dds
|
||||
Space_orange.cube.front.png sky/Space_orange.cube.front.dds
|
||||
|
|
|
@ -55,7 +55,7 @@ void Client::run(server_handle* const localHandle) {
|
|||
}
|
||||
camera.update();
|
||||
pipeline->lookFrom(camera);
|
||||
pipeline->LightInvDir = glm::vec3(glm::rotate(glm::mat4(1), deltaTime * .1f, glm::vec3(1, .5, .1)) * glm::vec4(pipeline->LightInvDir, 0));
|
||||
pipeline->LightInvDir = glm::vec3(glm::rotate(glm::mat4(1), deltaTime * .5f, glm::vec3(1, .5, .1)) * glm::vec4(pipeline->LightInvDir, 0));
|
||||
|
||||
{
|
||||
const auto ray_result = world->raycast(camera.getRay() * options.voxel_density);
|
||||
|
@ -101,7 +101,7 @@ void Client::run(server_handle* const localHandle) {
|
|||
pipeline->reloadShaders(options.renderer.voxel);
|
||||
}
|
||||
if(actions && render::UI::Actions::RendererTextures) {
|
||||
pipeline->reloadTextures(options.renderer.textures, options.renderer.mipMapLOD, options.renderer.anisotropy);
|
||||
pipeline->reloadTextures(options.renderer.textures, options.renderer.getMipmapLodBias(), options.renderer.getAnisotropy());
|
||||
}
|
||||
if(actions && render::UI::Actions::World) {
|
||||
//FIXME: server options world->setOptions(options.world);
|
||||
|
@ -159,10 +159,13 @@ void Client::run(server_handle* const localHandle) {
|
|||
};*/
|
||||
//world->getEntitiesModels(draw, frustum, offset, options.voxel_density);
|
||||
}
|
||||
if(state.look_at.has_value()) { // Indicator
|
||||
const auto model = glm::scale(glm::translate(glm::scale(glm::mat4(1), 1.f / glm::vec3(options.voxel_density)), glm::vec3(state.look_at.value().pos.second + state.look_at.value().offset - offset * glm::llvec3(options.voxel_density)) - glm::vec3(.5 + options.editor.tool.radius)), glm::vec3(1 + options.editor.tool.radius * 2));
|
||||
reports.models_count++;
|
||||
reports.tris_count += pipeline->drawIndicatorCube(model);
|
||||
{
|
||||
const auto pass = pipeline->beginIndicatorPass();
|
||||
if(state.look_at.has_value()) { // Indicator
|
||||
const auto model = glm::scale(glm::translate(glm::scale(glm::mat4(1), 1.f / glm::vec3(options.voxel_density)), glm::vec3(state.look_at.value().pos.second + state.look_at.value().offset - offset * glm::llvec3(options.voxel_density)) - glm::vec3(.5 + options.editor.tool.radius)), glm::vec3(1 + options.editor.tool.radius * 2));
|
||||
reports.models_count++;
|
||||
reports.tris_count += pass(model);
|
||||
}
|
||||
}
|
||||
pipeline->postProcess();
|
||||
render::UI::Get()->render();
|
||||
|
|
|
@ -35,8 +35,8 @@ public:
|
|||
|
||||
preferVulkan = config["render"]["prefer_vulkan"].value_or(preferVulkan);
|
||||
renderer.textures = config["render"]["textures"].value_or(renderer.textures);
|
||||
renderer.mipMapLOD = config["render"]["texture_quality"].value_or(renderer.mipMapLOD);
|
||||
renderer.anisotropy = config["render"]["texture_angular_quality"].value_or(renderer.anisotropy);
|
||||
renderer.textureQuality = config["render"]["texture_quality"].value_or(renderer.textureQuality);
|
||||
renderer.textureSharpness = config["render"]["texture_angular_quality"].value_or(renderer.textureSharpness);
|
||||
renderer.voxel.pbr = config["render"]["pbr"].value_or(renderer.voxel.pbr);
|
||||
renderer.voxel.triplanar = config["render"]["triplanar"].value_or(renderer.voxel.triplanar);
|
||||
renderer.voxel.stochastic = config["render"]["stochastic"].value_or(renderer.voxel.stochastic);
|
||||
|
@ -103,8 +103,8 @@ public:
|
|||
config.insert_or_assign("render", toml::table({
|
||||
{"prefer_vulkan", preferVulkan},
|
||||
{"textures", renderer.textures},
|
||||
{"texture_quality", renderer.mipMapLOD},
|
||||
{"texture_angular_quality", renderer.anisotropy},
|
||||
{"texture_quality", renderer.textureQuality},
|
||||
{"texture_angular_quality", renderer.textureSharpness},
|
||||
{"pbr", renderer.voxel.pbr},
|
||||
{"triplanar", renderer.voxel.triplanar},
|
||||
{"stochastic", renderer.voxel.stochastic},
|
||||
|
|
|
@ -22,7 +22,7 @@ struct passOptions {
|
|||
/// Transform texture UV
|
||||
bool stochastic = false;
|
||||
/// Active geometry pass
|
||||
bool geometry = false;
|
||||
bool geometry = true;
|
||||
/// Blend voxel with mixed materials (requires geometry)
|
||||
bool blend = true;
|
||||
/// Depth fog
|
||||
|
@ -44,14 +44,17 @@ struct renderOptions {
|
|||
/// Texture pack name
|
||||
std::string textures = "1024-realistic";
|
||||
/// Textures quality
|
||||
float mipMapLOD = -.5;
|
||||
int textureQuality = 100;
|
||||
/// Textures anisotropic mapping
|
||||
int anisotropy = 0;
|
||||
int textureSharpness = 0;
|
||||
/// Depth color
|
||||
glm::vec4 clear_color;
|
||||
/// Parallel processing frames
|
||||
/// Incease FPS but also a bit latency (Vulkan only)
|
||||
int inFlightFrames = 2;
|
||||
|
||||
constexpr float getMipmapLodBias() const { return 1 - (textureQuality / 100.f); }
|
||||
constexpr int getAnisotropy() const { return textureSharpness >= 1 ? (1 << (textureSharpness - 1)) : 0; }
|
||||
};
|
||||
|
||||
/// Rendering plateform interface
|
||||
|
@ -69,7 +72,7 @@ public:
|
|||
/// Get started entity program
|
||||
virtual std::function<size_t(render::Model *const, const std::vector<glm::mat4> &)> beginEntityPass() = 0;
|
||||
/// Draw cube indicator
|
||||
virtual size_t drawIndicatorCube(glm::mat4 model) = 0;
|
||||
virtual std::function<size_t(glm::mat4)> beginIndicatorPass() = 0;
|
||||
/// Apply postprocessing
|
||||
virtual void postProcess() = 0;
|
||||
/// Finalise frame
|
||||
|
|
|
@ -106,10 +106,12 @@ UI::Actions UI::draw(config::client::options &options, state::state &state, cons
|
|||
actions |= Actions::FillMode;
|
||||
}
|
||||
ImGui::Text("Textures '%s'", options.renderer.textures.c_str()); // MAYBE: select
|
||||
if (ImGui::SliderFloat("LOD", &options.renderer.mipMapLOD, -1, 1) |
|
||||
ImGui::SliderInt("Anisotropy", &options.renderer.anisotropy, 0, 8)) {
|
||||
if (ImGui::SliderInt("Quality", &options.renderer.textureQuality, 0, 200, "%d%%") |
|
||||
ImGui::SliderInt("Sharpness", &options.renderer.textureSharpness, 0, 8)) {
|
||||
actions |= Actions::RendererTextures;
|
||||
}
|
||||
if(ImGui::IsItemHovered())
|
||||
ImGui::SetTooltip("Better texture quality especially at low angles");
|
||||
ImGui::End();
|
||||
}
|
||||
|
||||
|
|
|
@ -14,7 +14,7 @@ std::unique_ptr<TextureArray> (*TextureArray::loadFunc)(const std::vector<std::s
|
|||
#define FOURCC_DXT3 0x33545844 // Equivalent to "DXT3" in ASCII
|
||||
#define FOURCC_DXT5 0x35545844 // Equivalent to "DXT5" in ASCII
|
||||
|
||||
std::optional<Image::properties> Image::Read(const std::string& imagepath, std::vector<unsigned char>& data) {
|
||||
std::optional<Image::properties> Image::Read(const std::string& imagepath, std::vector<unsigned char>& data, bool srgb) {
|
||||
|
||||
unsigned char header[124];
|
||||
properties info;
|
||||
|
@ -56,15 +56,18 @@ std::optional<Image::properties> Image::Read(const std::string& imagepath, std::
|
|||
switch(fourCC)
|
||||
{
|
||||
case FOURCC_DXT3:
|
||||
info.format = Format::BC2;
|
||||
info.format = srgb ? Format::BC2 : Format::BC2_UNORM;
|
||||
break;
|
||||
case FOURCC_DXT5:
|
||||
info.format = Format::BC3;
|
||||
info.format = srgb ? Format::BC3 : Format::BC3_UNORM;
|
||||
break;
|
||||
//MAYBE: VK_FORMAT_BC6H_SFLOAT_BLOCK
|
||||
default:
|
||||
return {};
|
||||
}
|
||||
//FIXME: miplevels with size < block size (2 last) are corrupted
|
||||
const uint maxMipmapLevels = 1 + std::floor(std::log2(std::max(info.size.height, info.size.width))) - 2;
|
||||
info.mipmapLevels = std::min(maxMipmapLevels, info.mipmapLevels);
|
||||
|
||||
return info;
|
||||
}
|
|
@ -20,8 +20,10 @@ public:
|
|||
enum class Format {
|
||||
/// DXT3 RGBA SRGB
|
||||
BC2 = 136,
|
||||
BC2_UNORM = 135,
|
||||
/// DXT5 RGBA SRGB
|
||||
BC3 = 138,
|
||||
BC3_UNORM = 137,
|
||||
// MAYBE: R8G8B8A8
|
||||
// MAYBE: For HDR BC6H_SFLOAT = 144,
|
||||
};
|
||||
|
@ -93,7 +95,7 @@ public:
|
|||
return requirement(props, Layout::SHADER_READ_ONLY, Usage::SAMPLED, Aspect::COLOR, 1, arraySize, cube); }
|
||||
};
|
||||
|
||||
static std::optional<properties> Read(const std::string&, std::vector<unsigned char>& data);
|
||||
static std::optional<properties> Read(const std::string&, std::vector<unsigned char>& data, bool srgb = true);
|
||||
};
|
||||
|
||||
/// Const image (single texture2D) with sampler
|
||||
|
@ -112,6 +114,7 @@ public:
|
|||
Wrap wrap = Wrap::MIRRORED_REPEAT;
|
||||
int anisotropy = 0;
|
||||
bool mipmap = true;
|
||||
float mipmapLod = 0;
|
||||
};
|
||||
|
||||
/// Only supports dds files
|
||||
|
|
|
@ -14,6 +14,9 @@ using namespace render::gl;
|
|||
constexpr auto GL_MAJOR = 4;
|
||||
constexpr auto GL_MINOR = 6;
|
||||
|
||||
#define CONTENT_DIR "content/"
|
||||
#define TEXTURES_DIR CONTENT_DIR "textures/"
|
||||
|
||||
Renderer::Renderer(const renderOptions& options):
|
||||
IndicatorCubeBuffer(Indicator::CUBE.first, Indicator::CUBE.second) {
|
||||
glGenVertexArrays(1, &VertexArrayID);
|
||||
|
@ -25,7 +28,7 @@ Renderer::Renderer(const renderOptions& options):
|
|||
IndicatorPass = std::make_unique<pass::ColorProgram>();
|
||||
|
||||
FogColor = glm::vec3(options.clear_color.x, options.clear_color.y, options.clear_color.z);
|
||||
loadTextures(options.textures, options.mipMapLOD, options.anisotropy);
|
||||
loadTextures(options.textures, options.getMipmapLodBias(), options.getAnisotropy());
|
||||
}
|
||||
|
||||
Renderer::~Renderer() {
|
||||
|
@ -107,10 +110,12 @@ std::function<size_t(render::Model *const, const std::vector<glm::mat4> &)> Rend
|
|||
};
|
||||
}
|
||||
|
||||
size_t Renderer::drawIndicatorCube(glm::mat4 model) {
|
||||
std::function<size_t(glm::mat4)> Renderer::beginIndicatorPass() {
|
||||
IndicatorPass->useIt();
|
||||
IndicatorPass->setup(this, model);
|
||||
return IndicatorCubeBuffer.draw();
|
||||
return [&](glm::mat4 model) {
|
||||
IndicatorPass->setup(this, model);
|
||||
return IndicatorCubeBuffer.draw();
|
||||
};
|
||||
}
|
||||
|
||||
void Renderer::postProcess() {
|
||||
|
@ -136,21 +141,25 @@ void Renderer::reloadTextures(const std::string& texturePath, float mipMapLOD, f
|
|||
}
|
||||
|
||||
void Renderer::unloadTextures() {
|
||||
glDeleteTextures(1, &HOSAtlas);
|
||||
glDeleteTextures(1, &NormalAtlas);
|
||||
glDeleteTextures(1, &TextureAtlas);
|
||||
HOSAtlas.reset();
|
||||
NormalAtlas.reset();
|
||||
TextureAtlas.reset();
|
||||
}
|
||||
void Renderer::loadTextures(const std::string& texturePath, float mipMapLOD, float anisotropy) {
|
||||
std::vector<std::string> terrainTextures;
|
||||
for(const auto& texture: world::materials::textures) {
|
||||
terrainTextures.emplace_back(texturePath + "/terrain/" + texture);
|
||||
}
|
||||
const auto ani = anisotropy >= 1 ? (1 << (static_cast<int>(anisotropy)-1)) : 0;
|
||||
TextureAtlas = pass::Program::loadTextureArray(terrainTextures, "", mipMapLOD, ani);
|
||||
NormalAtlas = pass::Program::loadTextureArray(terrainTextures, ".nrm", mipMapLOD, ani);
|
||||
HOSAtlas = pass::Program::loadTextureArray(terrainTextures, ".hos", mipMapLOD, ani);
|
||||
auto makePaths = [&](const std::string& suffix) {
|
||||
terrainTextures.clear();
|
||||
for(const auto& texture: world::materials::textures) {
|
||||
terrainTextures.emplace_back(TEXTURES_DIR + texturePath + "/terrain/" + texture + suffix + ".dds");
|
||||
}
|
||||
return terrainTextures;
|
||||
};
|
||||
auto sampling = Texture::sampling{true, true, Texture::Wrap::REPEAT, anisotropy, true, mipMapLOD};
|
||||
TextureAtlas = TextureArray::LoadFromFiles(makePaths(""), sampling);
|
||||
NormalAtlas = TextureArray::LoadFromFiles(makePaths(".nrm"), sampling);
|
||||
HOSAtlas = TextureArray::LoadFromFiles(makePaths(".hos"), sampling);
|
||||
|
||||
Skybox = pass::Program::loadTextureCube(texturePath + "/sky/Space_tray");
|
||||
Skybox = TextureCube::LoadFromFiles(TEXTURES_DIR + texturePath + "/sky/Space_tray.cube", {});
|
||||
}
|
||||
|
||||
void Renderer::lookFrom(const Camera& camera) {
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
#include "pass/SkyProgram.hpp"
|
||||
#include "pass/ColorProgram.hpp"
|
||||
#include "api/Models.hpp"
|
||||
#include "api/Images.hpp"
|
||||
|
||||
namespace render::gl {
|
||||
|
||||
|
@ -28,22 +29,22 @@ public:
|
|||
}
|
||||
|
||||
GLuint getTextureAtlas() const {
|
||||
return TextureAtlas;
|
||||
return TextureAtlas->getId();
|
||||
}
|
||||
GLuint getNormalAtlas() const {
|
||||
return NormalAtlas;
|
||||
return NormalAtlas->getId();
|
||||
}
|
||||
GLuint getHOSAtlas() const {
|
||||
return HOSAtlas;
|
||||
return HOSAtlas->getId();
|
||||
}
|
||||
GLuint getSkyTexture() const {
|
||||
return Skybox;
|
||||
return Skybox->getId();
|
||||
}
|
||||
|
||||
void beginFrame() override;
|
||||
std::function<size_t(render::LodModel *const, glm::mat4, glm::vec4, float)> beginWorldPass() override;
|
||||
std::function<size_t(render::Model *const, const std::vector<glm::mat4>&)> beginEntityPass() override;
|
||||
size_t drawIndicatorCube(glm::mat4 model) override;
|
||||
std::function<size_t(glm::mat4)> beginIndicatorPass() override;
|
||||
void postProcess() override;
|
||||
void endFrame() override;
|
||||
void swapBuffer(Window&) override;
|
||||
|
@ -73,10 +74,10 @@ private:
|
|||
glm::mat4 ProjectionMatrix;
|
||||
glm::mat4 ViewMatrix;
|
||||
|
||||
GLuint TextureAtlas;
|
||||
GLuint NormalAtlas;
|
||||
GLuint HOSAtlas;
|
||||
GLuint Skybox;
|
||||
std::unique_ptr<TextureArray> TextureAtlas;
|
||||
std::unique_ptr<TextureArray> NormalAtlas;
|
||||
std::unique_ptr<TextureArray> HOSAtlas;
|
||||
std::unique_ptr<TextureCube> Skybox;
|
||||
|
||||
/// Draw skybox
|
||||
bool SkyEnable;
|
||||
|
|
|
@ -1,9 +0,0 @@
|
|||
#include "Texture.hpp"
|
||||
|
||||
#include "texture.hpp"
|
||||
|
||||
using namespace render::gl;
|
||||
|
||||
GLuint Texture::CreatePtr(const std::string &name, bool linear) {
|
||||
return loadDDS("content/textures/" + name + ".dds", linear);
|
||||
}
|
|
@ -1,13 +0,0 @@
|
|||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <GLFW/glfw3.h>
|
||||
|
||||
namespace render::gl {
|
||||
|
||||
class Texture {
|
||||
public:
|
||||
static GLuint CreatePtr(const std::string &name, bool linear);
|
||||
};
|
||||
|
||||
}
|
|
@ -4,7 +4,7 @@
|
|||
#include <GL/gl3w.h>
|
||||
#include <imgui_impl_glfw.h>
|
||||
#include <imgui_impl_opengl3.h>
|
||||
#include "Texture.hpp"
|
||||
#include <string>
|
||||
|
||||
using namespace render::gl;
|
||||
|
||||
|
@ -12,7 +12,7 @@ UI::UI(GLFWwindow *window): render::UI() {
|
|||
// Setup Platform/Renderer bindings
|
||||
ImGui_ImplGlfw_InitForOpenGL(window, true);
|
||||
ImGui_ImplOpenGL3_Init("#version 130");
|
||||
aim = Texture::CreatePtr("ui/Aim", false);
|
||||
aim = Texture::LoadFromFile("content/textures/ui/Aim.dds", {false, false, Texture::Wrap::MIRRORED_REPEAT, 0, false});
|
||||
}
|
||||
UI::~UI() {
|
||||
ImGui_ImplGlfw_Shutdown();
|
||||
|
@ -22,7 +22,7 @@ UI::~UI() {
|
|||
UI::Actions UI::draw(config::client::options &o, state::state &s, const state::reports &r) {
|
||||
ImGui_ImplOpenGL3_NewFrame();
|
||||
ImGui_ImplGlfw_NewFrame();
|
||||
return render::UI::draw(o, s, r, aim);
|
||||
return render::UI::draw(o, s, r, aim->getId());
|
||||
}
|
||||
void UI::render() {
|
||||
ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData());
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#pragma once
|
||||
|
||||
#include "../UI.hpp"
|
||||
#include "api/Images.hpp"
|
||||
struct GLFWwindow;
|
||||
class Window;
|
||||
|
||||
|
@ -19,6 +20,6 @@ public:
|
|||
void render() override;
|
||||
|
||||
private:
|
||||
intptr_t aim;
|
||||
std::unique_ptr<Texture> aim;
|
||||
};
|
||||
}
|
|
@ -0,0 +1,189 @@
|
|||
#include "Images.hpp"
|
||||
#include "../../../../core/utils/logger.hpp"
|
||||
#include <algorithm>
|
||||
#include <string>
|
||||
|
||||
using namespace render::gl;
|
||||
|
||||
Image::~Image() {
|
||||
glDeleteTextures(1, &id);
|
||||
}
|
||||
|
||||
GLenum getGLFormat(render::Image::Format format) {
|
||||
switch (format) {
|
||||
case render::Image::Format::BC2:
|
||||
case render::Image::Format::BC2_UNORM:
|
||||
return GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT;
|
||||
|
||||
case render::Image::Format::BC3:
|
||||
case render::Image::Format::BC3_UNORM:
|
||||
return GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT;
|
||||
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
GLuint createImage(const Image::requirement& req, render::data_view data) {
|
||||
GLuint textureID;
|
||||
glGenTextures(1, &textureID);
|
||||
glBindTexture(GL_TEXTURE_2D, textureID);
|
||||
glPixelStorei(GL_UNPACK_ALIGNMENT,1);
|
||||
glTextureParameteri(textureID, GL_TEXTURE_MAX_LEVEL, req.mipmapLevels-1);
|
||||
|
||||
GLenum format = getGLFormat(req.format);
|
||||
unsigned int blockSize = /*(format == GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT) ? 8 :*/ 16;
|
||||
unsigned int offset = 0;
|
||||
|
||||
int width = req.size.width;
|
||||
int height = req.size.height;
|
||||
/* load the mipmaps */
|
||||
for (unsigned int level = 0; level < req.mipmapLevels && (width || height); ++level) {
|
||||
unsigned int size = ((width+3)/4)*((height+3)/4)*blockSize;
|
||||
assert(data.size >= offset + size);
|
||||
glCompressedTexImage2D(GL_TEXTURE_2D, level, format, width, height, 0, size, static_cast<const uint8_t*>(data.ptr) + offset);
|
||||
|
||||
offset += size;
|
||||
width /= 2;
|
||||
height /= 2;
|
||||
|
||||
// Deal with Non-Power-Of-Two textures. This code is not included in the webpage to reduce clutter.
|
||||
if(width < 1) width = 1;
|
||||
if(height < 1) height = 1;
|
||||
}
|
||||
|
||||
return textureID;
|
||||
}
|
||||
void applySampler(GLuint textureID, const Texture::sampling& props) {
|
||||
auto getFilter = [](bool linear, bool mipmap) { return linear ?
|
||||
(mipmap ? GL_LINEAR_MIPMAP_LINEAR : GL_LINEAR) : (mipmap ? GL_NEAREST_MIPMAP_NEAREST : GL_NEAREST); };
|
||||
auto wrap = [](Texture::Wrap wrap) {
|
||||
switch (wrap) {
|
||||
case Texture::Wrap::CLAMP_TO_EDGE:
|
||||
return GL_CLAMP_TO_EDGE;
|
||||
case Texture::Wrap::CLAMP_TO_BORDER:
|
||||
return GL_CLAMP_TO_BORDER;
|
||||
case Texture::Wrap::MIRRORED_REPEAT:
|
||||
return GL_MIRRORED_REPEAT;
|
||||
|
||||
case Texture::Wrap::REPEAT:
|
||||
default:
|
||||
return GL_REPEAT;
|
||||
}
|
||||
}(props.wrap);
|
||||
|
||||
glTextureParameteri(textureID, GL_TEXTURE_MAG_FILTER, getFilter(props.magLinear, props.mipmap));
|
||||
glTextureParameteri(textureID, GL_TEXTURE_MIN_FILTER, getFilter(props.minLinear, props.mipmap));
|
||||
glTextureParameterf(textureID, GL_TEXTURE_LOD_BIAS, props.mipmapLod);
|
||||
glTextureParameterf(textureID, GL_TEXTURE_MAX_ANISOTROPY, props.anisotropy);
|
||||
glTextureParameteri(textureID, GL_TEXTURE_WRAP_S, wrap);
|
||||
glTextureParameteri(textureID, GL_TEXTURE_WRAP_T, wrap);
|
||||
glTextureParameteri(textureID, GL_TEXTURE_WRAP_R, wrap);
|
||||
}
|
||||
|
||||
std::unique_ptr<Texture> Texture::LoadFromFile(const std::string& path, const sampling& props) {
|
||||
std::vector<unsigned char> data;
|
||||
auto header = [&] {
|
||||
if (auto header = render::Image::Read(path, data)) {
|
||||
return header.value();
|
||||
}
|
||||
FATAL("Cannot read texture");
|
||||
}();
|
||||
|
||||
auto id = createImage(requirement::Texture(header), data);
|
||||
if(!id) {
|
||||
FATAL("Cannot create texture image");
|
||||
}
|
||||
applySampler(id, props);
|
||||
|
||||
return std::unique_ptr<Texture>(new Texture(id));
|
||||
}
|
||||
|
||||
std::unique_ptr<TextureCube> TextureCube::LoadFromFiles(const std::array<std::string, 6>& paths, const sampling& props) {
|
||||
std::vector<unsigned char> data;
|
||||
auto header = [&] {
|
||||
if (auto header = render::Image::Read(paths.front(), data)) {
|
||||
return header.value();
|
||||
}
|
||||
FATAL("Cannot read first texture");
|
||||
}();
|
||||
auto req = requirement::Texture(header);
|
||||
|
||||
|
||||
GLuint textureID;
|
||||
{
|
||||
GLenum format = getGLFormat(header.format);
|
||||
glCreateTextures(GL_TEXTURE_CUBE_MAP, 1, &textureID);
|
||||
glTextureStorage2D(textureID, 1, format, header.size.width, header.size.height);
|
||||
|
||||
ushort layer = 0;
|
||||
for (auto imagepath = paths.begin(); imagepath != paths.end(); ++imagepath, ++layer) {
|
||||
data.clear();
|
||||
if (!render::Image::Read(*imagepath, data).has_value()) {
|
||||
FATAL("Cannot read texture");
|
||||
}
|
||||
GLuint subTextureID = createImage(req, data);
|
||||
glCopyImageSubData(subTextureID, GL_TEXTURE_2D, 0, 0, 0, 0, textureID, GL_TEXTURE_CUBE_MAP, 0, 0, 0, layer, header.size.width, header.size.height, 1);
|
||||
glDeleteTextures(1, &subTextureID);
|
||||
}
|
||||
}
|
||||
glTextureParameteri(textureID, GL_TEXTURE_MAX_LEVEL, header.mipmapLevels-1);
|
||||
applySampler(textureID, props);
|
||||
|
||||
return std::unique_ptr<TextureCube>(new TextureCube(textureID));
|
||||
}
|
||||
std::unique_ptr<TextureCube> TextureCube::LoadFromFiles(const std::string& prefix, const sampling& props) {
|
||||
const std::array<std::string, 6> faces {
|
||||
"right",
|
||||
"left",
|
||||
"top",
|
||||
"bottom",
|
||||
"front",
|
||||
"back"
|
||||
};
|
||||
std::array<std::string, 6> paths;
|
||||
std::transform(faces.begin(), faces.end(), paths.begin(),
|
||||
[prefix](const std::string &face) -> std::string { return prefix + "." + face + ".dds"; });
|
||||
return LoadFromFiles(paths, props);
|
||||
}
|
||||
|
||||
std::unique_ptr<TextureArray> TextureArray::LoadFromFiles(const std::vector<std::string>& paths, const sampling& props) {
|
||||
std::vector<unsigned char> data;
|
||||
auto header = [&] {
|
||||
if (auto header = render::Image::Read(paths.front(), data)) {
|
||||
return header.value();
|
||||
}
|
||||
FATAL("Cannot read first texture");
|
||||
}();
|
||||
auto req = requirement::Texture(header);
|
||||
|
||||
GLuint textureID;
|
||||
{
|
||||
GLenum format = getGLFormat(header.format);
|
||||
glCreateTextures(GL_TEXTURE_2D_ARRAY, 1, &textureID);
|
||||
glTextureStorage3D(textureID, header.mipmapLevels, format, header.size.width, header.size.height, paths.size());
|
||||
|
||||
ushort layer = 0;
|
||||
for (auto imagepath = paths.begin(); imagepath != paths.end(); ++imagepath, ++layer) {
|
||||
data.clear();
|
||||
if (!render::Image::Read(*imagepath, data).has_value()) {
|
||||
FATAL("Cannot read texture");
|
||||
}
|
||||
GLuint subTextureID = createImage(req, data);
|
||||
auto width = header.size.width;
|
||||
auto height = header.size.height;
|
||||
for (uint level = 0; level < header.mipmapLevels; level++) {
|
||||
glCopyImageSubData(subTextureID, GL_TEXTURE_2D, level, 0, 0, 0, textureID, GL_TEXTURE_2D_ARRAY, level, 0, 0, layer, width, height, 1);
|
||||
width /= 2;
|
||||
height /= 2;
|
||||
|
||||
if(width < 1) width = 1;
|
||||
if(height < 1) height = 1;
|
||||
}
|
||||
glDeleteTextures(1, &subTextureID);
|
||||
}
|
||||
}
|
||||
glTextureParameteri(textureID, GL_TEXTURE_MAX_LEVEL, header.mipmapLevels-1);
|
||||
applySampler(textureID, props);
|
||||
return std::unique_ptr<TextureArray>(new TextureArray(paths.size(), textureID));
|
||||
}
|
|
@ -0,0 +1,45 @@
|
|||
#pragma once
|
||||
|
||||
#include "../../api/Images.hpp"
|
||||
#include <GL/gl3w.h>
|
||||
|
||||
namespace render::gl {
|
||||
|
||||
class Image: public render::Image {
|
||||
public:
|
||||
virtual ~Image();
|
||||
|
||||
constexpr GLuint getId() const { return id; }
|
||||
|
||||
protected:
|
||||
Image(GLuint id): id(id) { }
|
||||
GLuint id;
|
||||
};
|
||||
|
||||
class Texture: public render::Texture, public Image {
|
||||
public:
|
||||
static std::unique_ptr<Texture> LoadFromFile(const std::string&, const sampling&);
|
||||
|
||||
protected:
|
||||
Texture(GLuint id): gl::Image(id) { }
|
||||
};
|
||||
|
||||
class TextureCube: public render::TextureCube, public Texture {
|
||||
public:
|
||||
/// Looks for .right.dds, .left.dds, .top.dds, .bottom.dds, .front.dds, .back.dds
|
||||
static std::unique_ptr<TextureCube> LoadFromFiles(const std::string& prefix, const sampling&);
|
||||
static std::unique_ptr<TextureCube> LoadFromFiles(const std::array<std::string, 6>& paths, const sampling&);
|
||||
|
||||
protected:
|
||||
TextureCube(GLuint id): Texture(id) { }
|
||||
};
|
||||
|
||||
class TextureArray: public render::TextureArray, public Texture {
|
||||
public:
|
||||
static std::unique_ptr<TextureArray> LoadFromFiles(const std::vector<std::string>&, const sampling&);
|
||||
|
||||
protected:
|
||||
TextureArray(uint32_t size, GLuint id): render::TextureArray(size), Texture(id) { }
|
||||
};
|
||||
|
||||
}
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
#include <algorithm>
|
||||
#include <stdexcept>
|
||||
#include "../texture.hpp"
|
||||
#include "../api/Images.hpp"
|
||||
|
||||
#define CONTENT_DIR "content/"
|
||||
#define SHADER_DIR CONTENT_DIR "shaders/"
|
||||
|
@ -45,28 +45,27 @@ void Program::useIt() {
|
|||
glUseProgram(ProgramID);
|
||||
}
|
||||
|
||||
/*
|
||||
GLuint Program::loadTexture(const std::string& name, bool linear) {
|
||||
return loadDDS(TEXTURES_DIR + name + ".dds", linear);
|
||||
auto img = render::gl::Texture::LoadFromFile(TEXTURES_DIR + name + ".dds", {linear, linear});
|
||||
auto id = img->getId();
|
||||
std::free(img.release());
|
||||
return id;
|
||||
}
|
||||
GLuint Program::loadTextureArray(const std::vector<std::string> &names, const std::string& suffix, float mipMapLOD, float anisotropy) {
|
||||
|
||||
std::vector<std::string> paths;
|
||||
std::transform(names.begin(), names.end(), std::back_inserter(paths),
|
||||
[suffix](const std::string &name) -> std::string { return TEXTURES_DIR + name + suffix + ".dds"; });
|
||||
return loadDDSArray(paths, mipMapLOD, anisotropy);
|
||||
|
||||
auto img = render::gl::TextureArray::LoadFromFiles(paths, {true, true, render::Texture::Wrap::REPEAT, anisotropy, true, mipMapLOD});
|
||||
auto id = img->getId();
|
||||
std::free(img.release());
|
||||
return id;
|
||||
}
|
||||
GLuint Program::loadTextureCube(const std::string &name) {
|
||||
|
||||
std::array<std::string, 6> faces {
|
||||
"right",
|
||||
"left",
|
||||
"top",
|
||||
"bottom",
|
||||
"front",
|
||||
"back"
|
||||
};
|
||||
std::array<std::string, 6> paths;
|
||||
std::transform(faces.begin(), faces.end(), paths.begin(),
|
||||
[name](const std::string &face) -> std::string { return TEXTURES_DIR + name + ".cube." + face + ".dds"; });
|
||||
return loadDDSCube(paths);
|
||||
}
|
||||
auto img = render::gl::TextureCube::LoadFromFiles(TEXTURES_DIR + name + ".cube", {});
|
||||
auto id = img->getId();
|
||||
std::free(img.release());
|
||||
return id;
|
||||
}*/
|
|
@ -23,10 +23,6 @@ namespace pass {
|
|||
/// Bind program
|
||||
void useIt();
|
||||
|
||||
static GLuint loadTexture(const std::string &name, bool linear = true);
|
||||
static GLuint loadTextureArray(const std::vector<std::string> &names, const std::string &suffix = "", float mipMapLOD = 0, float anisotropy = 0);
|
||||
static GLuint loadTextureCube(const std::string &name);
|
||||
|
||||
protected:
|
||||
/// Get shaders name prefix
|
||||
virtual std::string getName() const = 0;
|
||||
|
|
|
@ -1,261 +0,0 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <string>
|
||||
#include <cassert>
|
||||
#include <cmath>
|
||||
#include <vector>
|
||||
#include <iostream>
|
||||
#include <array>
|
||||
|
||||
#include <GL/gl3w.h>
|
||||
#include <GLFW/glfw3.h>
|
||||
|
||||
#define FOURCC_DXT1 0x31545844 // Equivalent to "DXT1" in ASCII
|
||||
#define FOURCC_DXT3 0x33545844 // Equivalent to "DXT3" in ASCII
|
||||
#define FOURCC_DXT5 0x35545844 // Equivalent to "DXT5" in ASCII
|
||||
|
||||
GLuint loadDDS(const std::string& imagepath, bool linear){
|
||||
|
||||
unsigned char header[124];
|
||||
|
||||
FILE *fp;
|
||||
|
||||
/* try to open the file */
|
||||
fp = fopen(imagepath.c_str(), "rb");
|
||||
if (fp == NULL){
|
||||
printf("%s could not be opened.\n", imagepath.c_str()); getchar();
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* verify the type of file */
|
||||
char filecode[4];
|
||||
fread(filecode, 1, 4, fp);
|
||||
if (strncmp(filecode, "DDS ", 4) != 0) {
|
||||
fclose(fp);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* get the surface desc */
|
||||
fread(&header, 124, 1, fp);
|
||||
|
||||
unsigned int height = *(unsigned int*)&(header[8 ]);
|
||||
unsigned int width = *(unsigned int*)&(header[12]);
|
||||
unsigned int linearSize = *(unsigned int*)&(header[16]);
|
||||
unsigned int mipMapCount = *(unsigned int*)&(header[24]);
|
||||
unsigned int fourCC = *(unsigned int*)&(header[80]);
|
||||
|
||||
|
||||
unsigned char * buffer;
|
||||
unsigned int bufsize;
|
||||
/* how big is it going to be including all mipmaps? */
|
||||
bufsize = mipMapCount > 1 ? linearSize * 2 : linearSize;
|
||||
buffer = (unsigned char*)malloc(bufsize * sizeof(unsigned char));
|
||||
fread(buffer, 1, bufsize, fp);
|
||||
/* close the file pointer */
|
||||
fclose(fp);
|
||||
|
||||
unsigned int format;
|
||||
switch(fourCC)
|
||||
{
|
||||
case FOURCC_DXT1:
|
||||
format = GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT;
|
||||
break;
|
||||
case FOURCC_DXT3:
|
||||
format = GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT;
|
||||
break;
|
||||
case FOURCC_DXT5:
|
||||
format = GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT;
|
||||
break;
|
||||
default:
|
||||
free(buffer);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Create one OpenGL texture
|
||||
GLuint textureID;
|
||||
glGenTextures(1, &textureID);
|
||||
|
||||
// "Bind" the newly created texture : all future texture functions will modify this texture
|
||||
glBindTexture(GL_TEXTURE_2D, textureID);
|
||||
glPixelStorei(GL_UNPACK_ALIGNMENT,1);
|
||||
|
||||
unsigned int blockSize = (format == GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT) ? 8 : 16;
|
||||
unsigned int offset = 0;
|
||||
|
||||
/* load the mipmaps */
|
||||
for (unsigned int level = 0; level < mipMapCount && (width || height); ++level)
|
||||
{
|
||||
unsigned int size = ((width+3)/4)*((height+3)/4)*blockSize;
|
||||
glCompressedTexImage2D(GL_TEXTURE_2D, level, format, width, height,
|
||||
0, size, buffer + offset);
|
||||
|
||||
offset += size;
|
||||
width /= 2;
|
||||
height /= 2;
|
||||
|
||||
// Deal with Non-Power-Of-Two textures. This code is not included in the webpage to reduce clutter.
|
||||
if(width < 1) width = 1;
|
||||
if(height < 1) height = 1;
|
||||
|
||||
}
|
||||
|
||||
free(buffer);
|
||||
|
||||
glTextureParameteri(textureID, GL_TEXTURE_MAG_FILTER, linear ? GL_LINEAR : GL_NEAREST);
|
||||
glTextureParameteri(textureID, GL_TEXTURE_MIN_FILTER, linear ? GL_LINEAR_MIPMAP_LINEAR : GL_NEAREST);
|
||||
|
||||
glGenerateTextureMipmap(textureID);
|
||||
|
||||
return textureID;
|
||||
|
||||
}
|
||||
|
||||
GLuint loadDDSArray(const std::vector<std::string>& imagepaths, float mipMapLOD, float anisotropy) {
|
||||
|
||||
unsigned char header[124];
|
||||
|
||||
auto imagepath = imagepaths.begin();
|
||||
|
||||
FILE *fp;
|
||||
|
||||
/* try to open the file */
|
||||
fp = fopen(imagepath->c_str(), "rb");
|
||||
if (fp == NULL)
|
||||
{
|
||||
printf("%s could not be opened.\n", imagepath->c_str());
|
||||
getchar();
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* verify the type of file */
|
||||
char filecode[4];
|
||||
fread(filecode, 1, 4, fp);
|
||||
if (strncmp(filecode, "DDS ", 4) != 0)
|
||||
{
|
||||
fclose(fp);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* get the surface desc */
|
||||
fread(&header, 124, 1, fp);
|
||||
|
||||
unsigned int mainHeight = *(unsigned int *)&(header[8]);
|
||||
unsigned int mainWidth = *(unsigned int *)&(header[12]);
|
||||
unsigned int mainFourCC = *(unsigned int *)&(header[80]);
|
||||
fclose(fp);
|
||||
|
||||
unsigned int mainFormat;
|
||||
switch (mainFourCC)
|
||||
{
|
||||
case FOURCC_DXT1:
|
||||
mainFormat = GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT;
|
||||
break;
|
||||
case FOURCC_DXT3:
|
||||
mainFormat = GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT;
|
||||
break;
|
||||
case FOURCC_DXT5:
|
||||
mainFormat = GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT;
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Create one OpenGL texture array
|
||||
GLuint textureID;
|
||||
glCreateTextures(GL_TEXTURE_2D_ARRAY, 1, &textureID);
|
||||
glTextureStorage3D(textureID, 1 + std::floor(std::log2(std::max(mainWidth, mainHeight))), mainFormat, mainWidth, mainHeight, imagepaths.size());
|
||||
|
||||
ushort layer = 0;
|
||||
for (imagepath = imagepaths.begin(); imagepath != imagepaths.end(); ++imagepath, ++layer)
|
||||
{
|
||||
GLuint subTextureID = loadDDS(*imagepath, false);
|
||||
glCopyImageSubData(subTextureID, GL_TEXTURE_2D, 0, 0, 0, 0, textureID, GL_TEXTURE_2D_ARRAY, 0, 0, 0, layer, mainWidth, mainHeight, 1);
|
||||
glDeleteTextures(1, &subTextureID);
|
||||
}
|
||||
|
||||
glTextureParameteri(textureID, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTextureParameteri(textureID, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
|
||||
glTextureParameterf(textureID, GL_TEXTURE_LOD_BIAS, mipMapLOD);
|
||||
glTextureParameterf(textureID, GL_TEXTURE_MAX_ANISOTROPY, anisotropy);
|
||||
|
||||
glGenerateTextureMipmap(textureID);
|
||||
|
||||
return textureID;
|
||||
|
||||
}
|
||||
|
||||
GLuint loadDDSCube(const std::array<std::string, 6>& imagepaths) {
|
||||
|
||||
unsigned char header[124];
|
||||
|
||||
auto imagepath = imagepaths.begin();
|
||||
|
||||
FILE *fp;
|
||||
|
||||
/* try to open the file */
|
||||
fp = fopen(imagepath->c_str(), "rb");
|
||||
if (fp == NULL)
|
||||
{
|
||||
printf("%s could not be opened.\n", imagepath->c_str());
|
||||
getchar();
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* verify the type of file */
|
||||
char filecode[4];
|
||||
fread(filecode, 1, 4, fp);
|
||||
if (strncmp(filecode, "DDS ", 4) != 0)
|
||||
{
|
||||
fclose(fp);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* get the surface desc */
|
||||
fread(&header, 124, 1, fp);
|
||||
|
||||
unsigned int mainHeight = *(unsigned int *)&(header[8]);
|
||||
unsigned int mainWidth = *(unsigned int *)&(header[12]);
|
||||
unsigned int mainFourCC = *(unsigned int *)&(header[80]);
|
||||
fclose(fp);
|
||||
|
||||
unsigned int mainFormat;
|
||||
switch (mainFourCC)
|
||||
{
|
||||
case FOURCC_DXT1:
|
||||
mainFormat = GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT;
|
||||
break;
|
||||
case FOURCC_DXT3:
|
||||
mainFormat = GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT;
|
||||
break;
|
||||
case FOURCC_DXT5:
|
||||
mainFormat = GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT;
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Create one OpenGL texture array
|
||||
GLuint textureID;
|
||||
glCreateTextures(GL_TEXTURE_CUBE_MAP, 1, &textureID);
|
||||
glTextureStorage2D(textureID, 1, mainFormat, mainWidth, mainHeight);
|
||||
|
||||
ushort layer = 0;
|
||||
for (imagepath = imagepaths.begin(); imagepath != imagepaths.end(); ++imagepath, ++layer)
|
||||
{
|
||||
GLuint subTextureID = loadDDS(*imagepath, false);
|
||||
glCopyImageSubData(subTextureID, GL_TEXTURE_2D, 0, 0, 0, 0, textureID, GL_TEXTURE_CUBE_MAP, 0, 0, 0, layer, mainWidth, mainHeight, 1);
|
||||
glDeleteTextures(1, &subTextureID);
|
||||
}
|
||||
|
||||
glTextureParameteri(textureID, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTextureParameteri(textureID, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTextureParameteri(textureID, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTextureParameteri(textureID, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
glTextureParameteri(textureID, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
|
||||
|
||||
glGenerateTextureMipmap(textureID);
|
||||
|
||||
return textureID;
|
||||
|
||||
}
|
|
@ -1,12 +0,0 @@
|
|||
#pragma once
|
||||
|
||||
#include <string.h>
|
||||
#include <vector>
|
||||
#include <array>
|
||||
|
||||
// Load a .DDS file using GLFW's own loader
|
||||
GLuint loadDDS(const std::string& imagepath, bool linear = true);
|
||||
// Load a list of .DDS files
|
||||
GLuint loadDDSArray(const std::vector<std::string> &imagepaths, float mipMapLOD, float anisotropy);
|
||||
// Load a .DDS cubemap
|
||||
GLuint loadDDSCube(const std::array<std::string, 6> &imagepaths);
|
|
@ -41,7 +41,7 @@ CommandCenter::CommandCenter(VkDevice device, const PhysicalDeviceInfo &info, co
|
|||
LOG_D("Samples: " << colorSamples);
|
||||
depthFormat = info.findDepthFormat();
|
||||
|
||||
loadAtlases(opt.textures);
|
||||
loadAtlases(opt.textures, opt.getAnisotropy(), opt.getMipmapLodBias());
|
||||
}
|
||||
CommandCenter::~CommandCenter() {
|
||||
if(!freed)
|
||||
|
@ -50,7 +50,7 @@ CommandCenter::~CommandCenter() {
|
|||
vkDestroyCommandPool(device, graphicsPool, ALLOC);
|
||||
}
|
||||
#include "../../../core/world/materials.hpp"
|
||||
void CommandCenter::loadAtlases(const std::string& textures) {
|
||||
void CommandCenter::loadAtlases(const std::string& textures, int anisotropy, float lodBias) {
|
||||
voxelTextureAtlas.reset();
|
||||
voxelNormalAtlas.reset();
|
||||
voxelHOSAtlas.reset();
|
||||
|
@ -64,9 +64,10 @@ void CommandCenter::loadAtlases(const std::string& textures) {
|
|||
}
|
||||
return paths;
|
||||
};
|
||||
voxelTextureAtlas = TextureArray::LoadFromFiles(makePaths(""), {}); //TODO: anisotropy/mipmap options
|
||||
voxelNormalAtlas = TextureArray::LoadFromFiles(makePaths(".nrm"), {});
|
||||
voxelHOSAtlas = TextureArray::LoadFromFiles(makePaths(".hos"), {});
|
||||
const auto sampling = Texture::sampling{true, true, Texture::Wrap::REPEAT, anisotropy, true, lodBias};
|
||||
voxelTextureAtlas = TextureArray::LoadFromFiles(makePaths(""), sampling);
|
||||
voxelNormalAtlas = TextureArray::LoadFromFiles(makePaths(".nrm"), sampling, false);
|
||||
voxelHOSAtlas = TextureArray::LoadFromFiles(makePaths(".hos"), sampling);
|
||||
|
||||
if(!(voxelTextureAtlas && voxelNormalAtlas && voxelHOSAtlas)) {
|
||||
FATAL("Failed to load texture pack!");
|
||||
|
@ -174,7 +175,7 @@ void CommandCenter::allocate(const std::vector<VkImageView>& views, const Pipeli
|
|||
bufferInfo.offset = 0;
|
||||
bufferInfo.range = sizeof(VoxelUBO);
|
||||
|
||||
std::array<VkWriteDescriptorSet, 2> descriptorWrites{};
|
||||
std::array<VkWriteDescriptorSet, 4> descriptorWrites{};
|
||||
descriptorWrites[0].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
|
||||
descriptorWrites[0].dstSet = voxelDescriptorSets[i];
|
||||
descriptorWrites[0].dstBinding = 0;
|
||||
|
@ -288,7 +289,7 @@ void CommandCenter::startWorldPass(uint32_t idx, const Subpass &worldPass) {
|
|||
vkCmdBindDescriptorSets(graphicsBuffers[idx], VK_PIPELINE_BIND_POINT_GRAPHICS, worldPass.layout, 0, 1, &voxelDescriptorSets[idx], 0, nullptr);
|
||||
}
|
||||
size_t CommandCenter::recordModel(uint32_t i, const Subpass &worldPass, const UniqueCurvaturePush& push, const LodModel *const modelBuffer) {
|
||||
vkCmdPushConstants(graphicsBuffers[i], worldPass.layout, VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT, 0, sizeof(push), &push);
|
||||
vkCmdPushConstants(graphicsBuffers[i], worldPass.layout, VK_SHADER_STAGE_VERTEX_BIT, 0, sizeof(push), &push);
|
||||
|
||||
VkBuffer vertexBuffers[] = {modelBuffer->getVertex()};
|
||||
VkDeviceSize offsets[] = {0};
|
||||
|
@ -299,11 +300,12 @@ size_t CommandCenter::recordModel(uint32_t i, const Subpass &worldPass, const Un
|
|||
return size;
|
||||
}
|
||||
void CommandCenter::startEntityPass(uint32_t) { }
|
||||
void CommandCenter::recordIndicator(uint32_t idx, const Subpass& indicPass, glm::mat4 model) {
|
||||
void CommandCenter::startIndicPass(uint32_t idx, const Subpass& indicPass) {
|
||||
vkCmdNextSubpass(graphicsBuffers[idx], VK_SUBPASS_CONTENTS_INLINE);
|
||||
vkCmdBindPipeline(graphicsBuffers[idx], VK_PIPELINE_BIND_POINT_GRAPHICS, indicPass.pipeline);
|
||||
vkCmdBindDescriptorSets(graphicsBuffers[idx], VK_PIPELINE_BIND_POINT_GRAPHICS, indicPass.layout, 0, 1, &indicDescriptorSets[idx], 0, nullptr);
|
||||
|
||||
}
|
||||
size_t CommandCenter::recordIndicator(uint32_t idx, const Subpass& indicPass, glm::mat4 model) {
|
||||
ModelPush push{model};
|
||||
vkCmdPushConstants(graphicsBuffers[idx], indicPass.layout, VK_SHADER_STAGE_VERTEX_BIT, 0, sizeof(push), &push);
|
||||
|
||||
|
@ -311,6 +313,7 @@ void CommandCenter::recordIndicator(uint32_t idx, const Subpass& indicPass, glm:
|
|||
VkDeviceSize offsets[] = {0};
|
||||
vkCmdBindVertexBuffers(graphicsBuffers[idx], 0, 1, vertexBuffers, offsets);
|
||||
vkCmdDraw(graphicsBuffers[idx], indicCubeBuffer->size, 1, 0, 0);
|
||||
return indicCubeBuffer->size;
|
||||
}
|
||||
void CommandCenter::recordPostprocess(uint32_t idx, const Subpass& skyPass, bool skybox) {
|
||||
vkCmdNextSubpass(graphicsBuffers[idx], VK_SUBPASS_CONTENTS_INLINE);
|
||||
|
|
|
@ -21,7 +21,8 @@ public:
|
|||
void startWorldPass(uint32_t idx, const Subpass&);
|
||||
size_t recordModel(uint32_t idx, const Subpass &worldPass, const UniqueCurvaturePush&, const LodModel *const);
|
||||
void startEntityPass(uint32_t idx);
|
||||
void recordIndicator(uint32_t idx, const Subpass&, glm::mat4 model);
|
||||
void startIndicPass(uint32_t idx, const Subpass&);
|
||||
size_t recordIndicator(uint32_t idx, const Subpass&, glm::mat4 model);
|
||||
void recordPostprocess(uint32_t idx, const Subpass&, bool skybox);
|
||||
void submitGraphics(uint32_t, VkSemaphore, VkSemaphore, VkFence);
|
||||
|
||||
|
@ -29,7 +30,7 @@ public:
|
|||
void free();
|
||||
|
||||
private:
|
||||
void loadAtlases(const std::string &texturePath);
|
||||
void loadAtlases(const std::string &texturePath, int anisotropy, float lodBias);
|
||||
|
||||
VkDevice device;
|
||||
|
||||
|
|
|
@ -4,7 +4,6 @@
|
|||
#include "../../../core/data/file.hpp"
|
||||
#include "../Renderer.hpp"
|
||||
#include "api/Models.hpp"
|
||||
#include <map>
|
||||
|
||||
#define CONTENT_DIR "content/"
|
||||
#define SHADER_DIR CONTENT_DIR "shaders/"
|
||||
|
@ -187,27 +186,6 @@ Pipeline::Pipeline(VkDevice device, const PhysicalDeviceInfo &info, const render
|
|||
}
|
||||
}
|
||||
// Common pipeline settings
|
||||
auto makeSpecialization = [](const std::map<uint32_t, data_view>& constants, std::vector<unsigned char>& speData, std::vector<VkSpecializationMapEntry>& speIndex) {
|
||||
//MAYBE: create class
|
||||
VkSpecializationInfo specialization;
|
||||
speData.resize(0);
|
||||
speIndex.resize(0);
|
||||
speData.reserve(constants.size()); //NOTE: Lower bound
|
||||
speIndex.reserve(constants.size());
|
||||
for(auto& constant: constants) {
|
||||
VkSpecializationMapEntry entry;
|
||||
entry.constantID = constant.first;
|
||||
entry.size = constant.second.size;
|
||||
entry.offset = speData.size();
|
||||
speData.resize(speData.size() + entry.size);
|
||||
memcpy(speData.data() + entry.offset, static_cast<const uint8_t*>(constant.second.ptr), entry.size);
|
||||
}
|
||||
specialization.dataSize = speData.size();
|
||||
specialization.pData = speData.data();
|
||||
specialization.mapEntryCount = speIndex.size();
|
||||
specialization.pMapEntries = speIndex.data();
|
||||
return specialization;
|
||||
};
|
||||
auto setShaders = [&](Subpass &pass, const std::string &shaderName, bool geometry = false, const VkSpecializationInfo* specialization = nullptr) -> std::vector<VkPipelineShaderStageCreateInfo>
|
||||
{
|
||||
auto createShaderModule = [&](const data::file_content &code) {
|
||||
|
@ -242,9 +220,9 @@ Pipeline::Pipeline(VkDevice device, const PhysicalDeviceInfo &info, const render
|
|||
if (geometry) {
|
||||
VkPipelineShaderStageCreateInfo geomShaderStageInfo{};
|
||||
geomShaderStageInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
|
||||
geomShaderStageInfo.stage = VK_SHADER_STAGE_FRAGMENT_BIT;
|
||||
data::file_content fsFile({SHADER_DIR + shaderName + ".gs.spv"});
|
||||
geomShaderStageInfo.module = pass.fsShader = createShaderModule(fsFile);
|
||||
geomShaderStageInfo.stage = VK_SHADER_STAGE_GEOMETRY_BIT;
|
||||
data::file_content gsFile({SHADER_DIR + shaderName + ".gs.spv"});
|
||||
geomShaderStageInfo.module = pass.gsShader = createShaderModule(gsFile);
|
||||
geomShaderStageInfo.pName = "main";
|
||||
geomShaderStageInfo.pSpecializationInfo = specialization;
|
||||
|
||||
|
@ -354,25 +332,61 @@ Pipeline::Pipeline(VkDevice device, const PhysicalDeviceInfo &info, const render
|
|||
{ // World pipeline
|
||||
VkPushConstantRange pushRange{};
|
||||
pushRange.offset = 0;
|
||||
pushRange.size = sizeof(ModelPush);
|
||||
pushRange.size = sizeof(UniqueCurvaturePush);
|
||||
pushRange.stageFlags = VK_SHADER_STAGE_VERTEX_BIT;
|
||||
setLayout(worldPass, {voxelDescriptorSet}, {pushRange});
|
||||
|
||||
auto unitSize = 1; //TODO: load from world.voxel_density
|
||||
std::vector<unsigned char> speData;
|
||||
std::vector<VkSpecializationMapEntry> speIndex;
|
||||
auto specialization = makeSpecialization({
|
||||
{0, data_view(&options.voxel.fog, sizeof(bool))},
|
||||
{1, data_view(&options.voxel.pbr, sizeof(bool))},
|
||||
{2, data_view(&options.voxel.triplanar, sizeof(bool))},
|
||||
{3, data_view(&options.voxel.stochastic, sizeof(bool))},
|
||||
{4, data_view(&options.voxel.blend, sizeof(bool))},
|
||||
{5, data_view(&options.voxel.curvature, sizeof(bool))},
|
||||
{6, data_view(&options.voxel.curv_depth, sizeof(bool))},
|
||||
{16, data_view(&unitSize, sizeof(int))}}, speData, speIndex);
|
||||
struct SpeData {
|
||||
bool fog;
|
||||
bool pbr;
|
||||
bool triplanar;
|
||||
bool stochastic;
|
||||
bool blend;
|
||||
bool curvature;
|
||||
bool curv_depth;
|
||||
int32_t unitSize;
|
||||
} speData;
|
||||
std::array<VkSpecializationMapEntry, 8> speIndex;
|
||||
speData.fog = options.voxel.fog;
|
||||
speIndex[0].constantID = 0;
|
||||
speIndex[0].offset = offsetof(SpeData, fog);
|
||||
speIndex[0].size = sizeof(SpeData::fog);
|
||||
speData.pbr = options.voxel.pbr;
|
||||
speIndex[1].constantID = 1;
|
||||
speIndex[1].offset = offsetof(SpeData, pbr);
|
||||
speIndex[1].size = sizeof(SpeData::pbr);
|
||||
speData.triplanar = options.voxel.triplanar;
|
||||
speIndex[2].constantID = 2;
|
||||
speIndex[2].offset = offsetof(SpeData, triplanar);
|
||||
speIndex[2].size = sizeof(SpeData::triplanar);
|
||||
speData.stochastic = options.voxel.stochastic;
|
||||
speIndex[3].constantID = 3;
|
||||
speIndex[3].offset = offsetof(SpeData, stochastic);
|
||||
speIndex[3].size = sizeof(SpeData::stochastic);
|
||||
speData.blend = options.voxel.blend;
|
||||
speIndex[4].constantID = 4;
|
||||
speIndex[4].offset = offsetof(SpeData, blend);
|
||||
speIndex[4].size = sizeof(SpeData::blend);
|
||||
speData.curvature = options.voxel.curvature;
|
||||
speIndex[5].constantID = 5;
|
||||
speIndex[5].offset = offsetof(SpeData, curvature);
|
||||
speIndex[5].size = sizeof(SpeData::curvature);
|
||||
speData.curv_depth = options.voxel.curv_depth;
|
||||
speIndex[6].constantID = 6;
|
||||
speIndex[6].offset = offsetof(SpeData, curv_depth);
|
||||
speIndex[6].size = sizeof(SpeData::curv_depth);
|
||||
speData.unitSize = 8; //TODO: load from world.voxel_density
|
||||
speIndex[7].constantID = 16;
|
||||
speIndex[7].offset = offsetof(SpeData, unitSize);
|
||||
speIndex[7].size = sizeof(SpeData::unitSize);
|
||||
VkSpecializationInfo specialization{};
|
||||
specialization.dataSize = sizeof(SpeData);
|
||||
specialization.pData = &speData;
|
||||
specialization.mapEntryCount = speIndex.size();
|
||||
specialization.pMapEntries = speIndex.data();
|
||||
|
||||
auto withGeometry = options.voxel.geometry; //MAYBE: && features.geometry
|
||||
auto shaderStages = setShaders(worldPass, withGeometry ? "Tris.geo" : "Tris", withGeometry, &specialization);
|
||||
auto withGeometry = options.voxel.geometry && info.features.geometryShader;
|
||||
auto shaderStages = setShaders(worldPass, withGeometry ? "Voxel.geo" : "Voxel", withGeometry, &specialization);
|
||||
|
||||
VkPipelineVertexInputStateCreateInfo vertexInputInfo{};
|
||||
vertexInputInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO;
|
||||
|
@ -496,6 +510,9 @@ Pipeline::Pipeline(VkDevice device, const PhysicalDeviceInfo &info, const render
|
|||
}
|
||||
Pipeline::~Pipeline() {
|
||||
auto destroy = [&](Subpass &pass) {
|
||||
if(pass.gsShader)
|
||||
vkDestroyShaderModule(device, pass.gsShader, ALLOC);
|
||||
|
||||
vkDestroyShaderModule(device, pass.fsShader, ALLOC);
|
||||
vkDestroyShaderModule(device, pass.vsShader, ALLOC);
|
||||
vkDestroyPipeline(device, pass.pipeline, ALLOC);
|
||||
|
@ -503,6 +520,7 @@ Pipeline::~Pipeline() {
|
|||
};
|
||||
|
||||
destroy(worldPass);
|
||||
destroy(indicPass);
|
||||
destroy(skyPass);
|
||||
|
||||
vkDestroyDescriptorSetLayout(device, voxelDescriptorSet, ALLOC);
|
||||
|
|
|
@ -6,6 +6,7 @@ namespace render::vk {
|
|||
|
||||
struct Subpass {
|
||||
VkShaderModule vsShader;
|
||||
VkShaderModule gsShader = nullptr;
|
||||
VkShaderModule fsShader;
|
||||
VkPipelineLayout layout;
|
||||
VkPipeline pipeline;
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue