mirror of
https://github.com/lubosz/overte.git
synced 2025-08-08 04:08:13 +02:00
resolve conflicts on merge with upstream/master
This commit is contained in:
commit
a3959109f1
34 changed files with 949 additions and 367 deletions
|
@ -73,7 +73,7 @@ endfunction()
|
||||||
|
|
||||||
|
|
||||||
macro(AUTOSCRIBE_SHADER_LIB)
|
macro(AUTOSCRIBE_SHADER_LIB)
|
||||||
|
message("Autoscribe running for ${TARGET_NAME}")
|
||||||
file(RELATIVE_PATH RELATIVE_LIBRARY_DIR_PATH ${CMAKE_CURRENT_SOURCE_DIR} "${HIFI_LIBRARY_DIR}")
|
file(RELATIVE_PATH RELATIVE_LIBRARY_DIR_PATH ${CMAKE_CURRENT_SOURCE_DIR} "${HIFI_LIBRARY_DIR}")
|
||||||
foreach(HIFI_LIBRARY ${ARGN})
|
foreach(HIFI_LIBRARY ${ARGN})
|
||||||
#if (NOT TARGET ${HIFI_LIBRARY})
|
#if (NOT TARGET ${HIFI_LIBRARY})
|
||||||
|
|
|
@ -9,7 +9,8 @@
|
||||||
|
|
||||||
macro(SETUP_HIFI_LIBRARY)
|
macro(SETUP_HIFI_LIBRARY)
|
||||||
|
|
||||||
project(${TARGET_NAME})
|
project(${TARGET_NAME})
|
||||||
|
message("Setting up project ${TARGET_NAME}")
|
||||||
|
|
||||||
# grab the implemenation and header files
|
# grab the implemenation and header files
|
||||||
file(GLOB_RECURSE LIB_SRCS "src/*.h" "src/*.cpp" "src/*.c")
|
file(GLOB_RECURSE LIB_SRCS "src/*.h" "src/*.cpp" "src/*.c")
|
||||||
|
@ -33,5 +34,8 @@ macro(SETUP_HIFI_LIBRARY)
|
||||||
foreach(QT_MODULE ${${TARGET_NAME}_DEPENDENCY_QT_MODULES})
|
foreach(QT_MODULE ${${TARGET_NAME}_DEPENDENCY_QT_MODULES})
|
||||||
target_link_libraries(${TARGET_NAME} Qt5::${QT_MODULE})
|
target_link_libraries(${TARGET_NAME} Qt5::${QT_MODULE})
|
||||||
endforeach()
|
endforeach()
|
||||||
|
|
||||||
|
# Don't make scribed shaders cumulative
|
||||||
|
set(AUTOSCRIBE_SHADER_LIB_SRC "")
|
||||||
|
|
||||||
endmacro(SETUP_HIFI_LIBRARY)
|
endmacro(SETUP_HIFI_LIBRARY)
|
6
examples/shaders/exampleSkyboxUserDataV2.json
Normal file
6
examples/shaders/exampleSkyboxUserDataV2.json
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
{
|
||||||
|
"ProceduralEntity":
|
||||||
|
{
|
||||||
|
"shaderUrl": "https://s3.amazonaws.com/Oculus/shadertoys/relentlessSkybox.fs"
|
||||||
|
}
|
||||||
|
}
|
144
examples/shaders/shadertoys/relentlessSkybox.fs
Normal file
144
examples/shaders/shadertoys/relentlessSkybox.fs
Normal file
|
@ -0,0 +1,144 @@
|
||||||
|
// srtuss, 2013
|
||||||
|
|
||||||
|
// collecting some design ideas for a new game project.
|
||||||
|
// no raymarching is used.
|
||||||
|
|
||||||
|
// if i could add a custom soundtrack, it'd use this one (essential for desired sensation)
|
||||||
|
// http://www.youtube.com/watch?v=1uFAu65tZpo
|
||||||
|
|
||||||
|
//#define GREEN_VERSION
|
||||||
|
|
||||||
|
// ** improved camera shaking
|
||||||
|
// ** cleaned up code
|
||||||
|
// ** added stuff to the gates
|
||||||
|
|
||||||
|
// *******************************************************************************************
|
||||||
|
// Please do NOT use this shader in your own productions/videos/games without my permission!
|
||||||
|
// If you'd still like to do so, please drop me a mail (stral@aon.at)
|
||||||
|
// *******************************************************************************************
|
||||||
|
float time = iGlobalTime;
|
||||||
|
|
||||||
|
vec2 rotate(vec2 p, float a) {
|
||||||
|
return vec2(p.x * cos(a) - p.y * sin(a), p.x * sin(a) + p.y * cos(a));
|
||||||
|
}
|
||||||
|
|
||||||
|
float box(vec2 p, vec2 b, float r) {
|
||||||
|
return length(max(abs(p) - b, 0.0)) - r;
|
||||||
|
}
|
||||||
|
|
||||||
|
// iq's ray-plane-intersection code
|
||||||
|
vec3 intersect(in vec3 o, in vec3 d, vec3 c, vec3 u, vec3 v)
|
||||||
|
{
|
||||||
|
vec3 q = o - c;
|
||||||
|
return vec3(
|
||||||
|
dot(cross(u, v), q),
|
||||||
|
dot(cross(q, u), d),
|
||||||
|
dot(cross(v, q), d)) / dot(cross(v, u), d);
|
||||||
|
}
|
||||||
|
|
||||||
|
// some noise functions for fast developing
|
||||||
|
float rand11(float p) {
|
||||||
|
return fract(sin(p * 591.32) * 43758.5357);
|
||||||
|
}
|
||||||
|
float rand12(vec2 p) {
|
||||||
|
return fract(sin(dot(p.xy, vec2(12.9898, 78.233))) * 43758.5357);
|
||||||
|
}
|
||||||
|
vec2 rand21(float p) {
|
||||||
|
return fract(vec2(sin(p * 591.32), cos(p * 391.32)));
|
||||||
|
}
|
||||||
|
vec2 rand22(in vec2 p)
|
||||||
|
{
|
||||||
|
return fract(vec2(sin(p.x * 591.32 + p.y * 154.077), cos(p.x * 391.32 + p.y * 49.077)));
|
||||||
|
}
|
||||||
|
|
||||||
|
float noise11(float p) {
|
||||||
|
float fl = floor(p);
|
||||||
|
return mix(rand11(fl), rand11(fl + 1.0), fract(p)); //smoothstep(0.0, 1.0, fract(p)));
|
||||||
|
}
|
||||||
|
float fbm11(float p) {
|
||||||
|
return noise11(p) * 0.5 + noise11(p * 2.0) * 0.25 + noise11(p * 5.0) * 0.125;
|
||||||
|
}
|
||||||
|
vec3 noise31(float p) {
|
||||||
|
return vec3(noise11(p), noise11(p + 18.952), noise11(p - 11.372)) * 2.0 - 1.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// something that looks a bit like godrays coming from the surface
|
||||||
|
float sky(vec3 p) {
|
||||||
|
float a = atan(p.x, p.z);
|
||||||
|
float t = time * 0.1;
|
||||||
|
float v = rand11(floor(a * 4.0 + t)) * 0.5 + rand11(floor(a * 8.0 - t)) * 0.25
|
||||||
|
+ rand11(floor(a * 16.0 + t)) * 0.125;
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
|
||||||
|
vec3 voronoi(in vec2 x)
|
||||||
|
{
|
||||||
|
vec2 n = floor(x); // grid cell id
|
||||||
|
vec2 f = fract(x);// grid internal position
|
||||||
|
vec2 mg;// shortest distance...
|
||||||
|
vec2 mr;// ..and second shortest distance
|
||||||
|
float md = 8.0, md2 = 8.0;
|
||||||
|
for(int j = -1; j <= 1; j ++)
|
||||||
|
{
|
||||||
|
for(int i = -1; i <= 1; i ++)
|
||||||
|
{
|
||||||
|
vec2 g = vec2(float(i), float(j)); // cell id
|
||||||
|
vec2 o = rand22(n + g);// offset to edge point
|
||||||
|
vec2 r = g + o - f;
|
||||||
|
|
||||||
|
float d = max(abs(r.x), abs(r.y));// distance to the edge
|
||||||
|
|
||||||
|
if(d < md)
|
||||||
|
{ md2 = md; md = d; mr = r; mg = g;}
|
||||||
|
else if(d < md2)
|
||||||
|
{ md2 = d;}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return vec3(n + mg, md2 - md);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
vec3 getSkyboxColor() {
|
||||||
|
vec3 rd = normalize(_normal);
|
||||||
|
vec3 ro = vec3(0, 0, 1);
|
||||||
|
float inten = 0.0;
|
||||||
|
|
||||||
|
// background
|
||||||
|
float sd = dot(rd, vec3(0.0, 1.0, 0.0));
|
||||||
|
inten = pow(1.0 - abs(sd), 20.0) + pow(sky(rd), 5.0) * step(0.0, rd.y) * 0.2;
|
||||||
|
|
||||||
|
vec3 its;
|
||||||
|
float v, g;
|
||||||
|
|
||||||
|
// voronoi floor layers
|
||||||
|
for(int i = 0; i < 4; i ++)
|
||||||
|
{
|
||||||
|
float layer = float(i);
|
||||||
|
its = intersect(ro, rd, vec3(0.0, -5.0 - layer * 5.0, 0.0), vec3(1.0, 0.0, 0.0), vec3(0.0, 0.0, 1.0));
|
||||||
|
if(its.x > 0.0)
|
||||||
|
{
|
||||||
|
vec3 vo = voronoi((its.yz) * 0.05 + 8.0 * rand21(float(i)));
|
||||||
|
v = exp(-100.0 * (vo.z - 0.02));
|
||||||
|
|
||||||
|
float fx = 0.0;
|
||||||
|
|
||||||
|
// add some special fx to lowest layer
|
||||||
|
if(i == 3)
|
||||||
|
{
|
||||||
|
float crd = 0.0; //fract(time * 0.2) * 50.0 - 25.0;
|
||||||
|
float fxi = cos(vo.x * 0.2 + time * 1.5);//abs(crd - vo.x);
|
||||||
|
fx = clamp(smoothstep(0.9, 1.0, fxi), 0.0, 0.9) * 1.0 * rand12(vo.xy);
|
||||||
|
fx *= exp(-3.0 * vo.z) * 2.0;
|
||||||
|
}
|
||||||
|
inten += v * 0.1 + fx;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inten *= 0.4 + (sin(time) * 0.5 + 0.5) * 0.6;
|
||||||
|
|
||||||
|
vec3 ct = vec3(0.6, 0.8, 9.0);
|
||||||
|
// find a color for the computed intensity
|
||||||
|
vec3 col = pow(vec3(inten), ct);
|
||||||
|
return col;
|
||||||
|
}
|
|
@ -113,7 +113,7 @@ endif()
|
||||||
target_link_libraries(${TARGET_NAME} ${BULLET_LIBRARIES})
|
target_link_libraries(${TARGET_NAME} ${BULLET_LIBRARIES})
|
||||||
|
|
||||||
# link required hifi libraries
|
# link required hifi libraries
|
||||||
link_hifi_libraries(shared octree environment gpu model render fbx networking entities avatars
|
link_hifi_libraries(shared octree environment gpu gpu-networking procedural model render fbx networking entities avatars
|
||||||
audio audio-client animation script-engine physics
|
audio audio-client animation script-engine physics
|
||||||
render-utils entities-renderer ui auto-updater
|
render-utils entities-renderer ui auto-updater
|
||||||
plugins display-plugins input-plugins)
|
plugins display-plugins input-plugins)
|
||||||
|
|
|
@ -26,4 +26,4 @@ find_package(PolyVox REQUIRED)
|
||||||
target_include_directories(${TARGET_NAME} SYSTEM PUBLIC ${POLYVOX_INCLUDE_DIRS})
|
target_include_directories(${TARGET_NAME} SYSTEM PUBLIC ${POLYVOX_INCLUDE_DIRS})
|
||||||
target_link_libraries(${TARGET_NAME} ${POLYVOX_LIBRARIES})
|
target_link_libraries(${TARGET_NAME} ${POLYVOX_LIBRARIES})
|
||||||
|
|
||||||
link_hifi_libraries(shared gpu script-engine render render-utils)
|
link_hifi_libraries(shared gpu gpu-networking procedural script-engine render render-utils)
|
||||||
|
|
|
@ -22,6 +22,7 @@
|
||||||
#include <PerfStat.h>
|
#include <PerfStat.h>
|
||||||
#include <SceneScriptingInterface.h>
|
#include <SceneScriptingInterface.h>
|
||||||
#include <ScriptEngine.h>
|
#include <ScriptEngine.h>
|
||||||
|
#include <procedural/Procedural.h>
|
||||||
#include <TextureCache.h>
|
#include <TextureCache.h>
|
||||||
|
|
||||||
#include "EntityTreeRenderer.h"
|
#include "EntityTreeRenderer.h"
|
||||||
|
@ -454,13 +455,24 @@ void EntityTreeRenderer::applyZonePropertiesToScene(std::shared_ptr<ZoneEntityIt
|
||||||
_viewState->endOverrideEnvironmentData();
|
_viewState->endOverrideEnvironmentData();
|
||||||
auto stage = scene->getSkyStage();
|
auto stage = scene->getSkyStage();
|
||||||
if (zone->getBackgroundMode() == BACKGROUND_MODE_SKYBOX) {
|
if (zone->getBackgroundMode() == BACKGROUND_MODE_SKYBOX) {
|
||||||
stage->getSkybox()->setColor(zone->getSkyboxProperties().getColorVec3());
|
auto skybox = stage->getSkybox();
|
||||||
|
skybox->setColor(zone->getSkyboxProperties().getColorVec3());
|
||||||
|
static QString userData;
|
||||||
|
if (userData != zone->getUserData()) {
|
||||||
|
userData = zone->getUserData();
|
||||||
|
QSharedPointer<Procedural> procedural(new Procedural(userData));
|
||||||
|
if (procedural->_enabled) {
|
||||||
|
skybox->setProcedural(procedural);
|
||||||
|
} else {
|
||||||
|
skybox->setProcedural(QSharedPointer<Procedural>());
|
||||||
|
}
|
||||||
|
}
|
||||||
if (zone->getSkyboxProperties().getURL().isEmpty()) {
|
if (zone->getSkyboxProperties().getURL().isEmpty()) {
|
||||||
stage->getSkybox()->setCubemap(gpu::TexturePointer());
|
skybox->setCubemap(gpu::TexturePointer());
|
||||||
} else {
|
} else {
|
||||||
// Update the Texture of the Skybox with the one pointed by this zone
|
// Update the Texture of the Skybox with the one pointed by this zone
|
||||||
auto cubeMap = DependencyManager::get<TextureCache>()->getTexture(zone->getSkyboxProperties().getURL(), CUBE_TEXTURE);
|
auto cubeMap = DependencyManager::get<TextureCache>()->getTexture(zone->getSkyboxProperties().getURL(), CUBE_TEXTURE);
|
||||||
stage->getSkybox()->setCubemap(cubeMap->getGPUTexture());
|
skybox->setCubemap(cubeMap->getGPUTexture());
|
||||||
}
|
}
|
||||||
stage->setBackgroundMode(model::SunSkyStage::SKY_BOX);
|
stage->setBackgroundMode(model::SunSkyStage::SKY_BOX);
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -21,6 +21,8 @@
|
||||||
#include <PerfStat.h>
|
#include <PerfStat.h>
|
||||||
|
|
||||||
#include "RenderableDebugableEntityItem.h"
|
#include "RenderableDebugableEntityItem.h"
|
||||||
|
#include "../render-utils/simple_vert.h"
|
||||||
|
#include "../render-utils/simple_frag.h"
|
||||||
|
|
||||||
EntityItemPointer RenderableBoxEntityItem::factory(const EntityItemID& entityID, const EntityItemProperties& properties) {
|
EntityItemPointer RenderableBoxEntityItem::factory(const EntityItemID& entityID, const EntityItemProperties& properties) {
|
||||||
return std::make_shared<RenderableBoxEntityItem>(entityID, properties);
|
return std::make_shared<RenderableBoxEntityItem>(entityID, properties);
|
||||||
|
@ -42,11 +44,18 @@ void RenderableBoxEntityItem::render(RenderArgs* args) {
|
||||||
glm::vec4 cubeColor(toGlm(getXColor()), getLocalRenderAlpha());
|
glm::vec4 cubeColor(toGlm(getXColor()), getLocalRenderAlpha());
|
||||||
|
|
||||||
if (!_procedural) {
|
if (!_procedural) {
|
||||||
_procedural.reset(new ProceduralInfo(this));
|
_procedural.reset(new Procedural(this->getUserData()));
|
||||||
|
_procedural->_vertexSource = simple_vert;
|
||||||
|
_procedural->_fragmentSource = simple_frag;
|
||||||
|
_procedural->_state->setCullMode(gpu::State::CULL_NONE);
|
||||||
|
_procedural->_state->setDepthTest(true, true, gpu::LESS_EQUAL);
|
||||||
|
_procedural->_state->setBlendFunction(false,
|
||||||
|
gpu::State::SRC_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::INV_SRC_ALPHA,
|
||||||
|
gpu::State::FACTOR_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::ONE);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_procedural->ready()) {
|
if (_procedural->ready()) {
|
||||||
_procedural->prepare(batch);
|
_procedural->prepare(batch, this->getDimensions());
|
||||||
DependencyManager::get<GeometryCache>()->renderSolidCube(batch, 1.0f, _procedural->getColor(cubeColor));
|
DependencyManager::get<GeometryCache>()->renderSolidCube(batch, 1.0f, _procedural->getColor(cubeColor));
|
||||||
} else {
|
} else {
|
||||||
DependencyManager::get<DeferredLightingEffect>()->renderSolidCube(batch, 1.0f, cubeColor);
|
DependencyManager::get<DeferredLightingEffect>()->renderSolidCube(batch, 1.0f, cubeColor);
|
||||||
|
|
|
@ -13,10 +13,11 @@
|
||||||
#define hifi_RenderableBoxEntityItem_h
|
#define hifi_RenderableBoxEntityItem_h
|
||||||
|
|
||||||
#include <BoxEntityItem.h>
|
#include <BoxEntityItem.h>
|
||||||
#include "RenderableEntityItem.h"
|
#include <procedural/Procedural.h>
|
||||||
#include "RenderableProceduralItem.h"
|
|
||||||
|
|
||||||
class RenderableBoxEntityItem : public BoxEntityItem, RenderableProceduralItem {
|
#include "RenderableEntityItem.h"
|
||||||
|
|
||||||
|
class RenderableBoxEntityItem : public BoxEntityItem {
|
||||||
public:
|
public:
|
||||||
static EntityItemPointer factory(const EntityItemID& entityID, const EntityItemProperties& properties);
|
static EntityItemPointer factory(const EntityItemID& entityID, const EntityItemProperties& properties);
|
||||||
|
|
||||||
|
@ -28,6 +29,8 @@ public:
|
||||||
virtual void setUserData(const QString& value);
|
virtual void setUserData(const QString& value);
|
||||||
|
|
||||||
SIMPLE_RENDERABLE()
|
SIMPLE_RENDERABLE()
|
||||||
|
private:
|
||||||
|
QSharedPointer<Procedural> _procedural;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -228,6 +228,14 @@ void RenderableParticleEffectEntityItem::updateRenderItem() {
|
||||||
// update vertex buffer
|
// update vertex buffer
|
||||||
auto vertexBuffer = payload.getVertexBuffer();
|
auto vertexBuffer = payload.getVertexBuffer();
|
||||||
size_t numBytes = sizeof(Vertex) * _vertices.size();
|
size_t numBytes = sizeof(Vertex) * _vertices.size();
|
||||||
|
|
||||||
|
if (numBytes == 0) {
|
||||||
|
vertexBuffer->resize(0);
|
||||||
|
auto indexBuffer = payload.getIndexBuffer();
|
||||||
|
indexBuffer->resize(0);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
vertexBuffer->resize(numBytes);
|
vertexBuffer->resize(numBytes);
|
||||||
gpu::Byte* data = vertexBuffer->editData();
|
gpu::Byte* data = vertexBuffer->editData();
|
||||||
memcpy(data, &(_vertices[0]), numBytes);
|
memcpy(data, &(_vertices[0]), numBytes);
|
||||||
|
@ -293,7 +301,7 @@ void RenderableParticleEffectEntityItem::updateRenderItem() {
|
||||||
payload.setPipeline(_untexturedPipeline);
|
payload.setPipeline(_untexturedPipeline);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
_scene->enqueuePendingChanges(pendingChanges);
|
_scene->enqueuePendingChanges(pendingChanges);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,60 +0,0 @@
|
||||||
//
|
|
||||||
// Created by Bradley Austin Davis on 2015/09/05
|
|
||||||
// Copyright 2013-2015 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
|
|
||||||
//
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
#ifndef hifi_RenderableProcedrualItem_h
|
|
||||||
#define hifi_RenderableProcedrualItem_h
|
|
||||||
|
|
||||||
#include <QtCore/qglobal.h>
|
|
||||||
#include <QtCore/QString>
|
|
||||||
#include <QtCore/QUrl>
|
|
||||||
#include <QtCore/QJsonObject>
|
|
||||||
|
|
||||||
#include <ShaderCache.h>
|
|
||||||
#include <gpu/Shader.h>
|
|
||||||
#include <gpu/Pipeline.h>
|
|
||||||
#include <gpu/Batch.h>
|
|
||||||
|
|
||||||
class EntityItem;
|
|
||||||
class QJsonObject;
|
|
||||||
|
|
||||||
class RenderableProceduralItem {
|
|
||||||
protected:
|
|
||||||
// FIXME better encapsulation
|
|
||||||
// FIXME better mechanism for extending to things rendered using shaders other than simple.slv
|
|
||||||
struct ProceduralInfo {
|
|
||||||
ProceduralInfo(EntityItem* entity);
|
|
||||||
void parse();
|
|
||||||
void parse(const QJsonObject&);
|
|
||||||
bool ready();
|
|
||||||
void prepare(gpu::Batch& batch);
|
|
||||||
glm::vec4 getColor(const glm::vec4& entityColor);
|
|
||||||
|
|
||||||
bool _enabled{ false };
|
|
||||||
uint8_t _version{ 1 };
|
|
||||||
gpu::PipelinePointer _pipeline;
|
|
||||||
gpu::ShaderPointer _vertexShader;
|
|
||||||
gpu::ShaderPointer _fragmentShader;
|
|
||||||
gpu::ShaderPointer _shader;
|
|
||||||
QString _shaderSource;
|
|
||||||
QString _shaderPath;
|
|
||||||
QUrl _shaderUrl;
|
|
||||||
quint64 _shaderModified{ 0 };
|
|
||||||
bool _pipelineDirty{ true };
|
|
||||||
int32_t _timeSlot{ gpu::Shader::INVALID_LOCATION };
|
|
||||||
int32_t _scaleSlot{ gpu::Shader::INVALID_LOCATION };
|
|
||||||
uint64_t _start{ 0 };
|
|
||||||
NetworkShaderPointer _networkShader;
|
|
||||||
EntityItem* _entity;
|
|
||||||
QJsonObject _uniforms;
|
|
||||||
};
|
|
||||||
|
|
||||||
QSharedPointer<ProceduralInfo> _procedural;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -21,6 +21,8 @@
|
||||||
#include <PerfStat.h>
|
#include <PerfStat.h>
|
||||||
|
|
||||||
#include "RenderableDebugableEntityItem.h"
|
#include "RenderableDebugableEntityItem.h"
|
||||||
|
#include "../render-utils/simple_vert.h"
|
||||||
|
#include "../render-utils/simple_frag.h"
|
||||||
|
|
||||||
EntityItemPointer RenderableSphereEntityItem::factory(const EntityItemID& entityID, const EntityItemProperties& properties) {
|
EntityItemPointer RenderableSphereEntityItem::factory(const EntityItemID& entityID, const EntityItemProperties& properties) {
|
||||||
return std::make_shared<RenderableSphereEntityItem>(entityID, properties);
|
return std::make_shared<RenderableSphereEntityItem>(entityID, properties);
|
||||||
|
@ -47,12 +49,19 @@ void RenderableSphereEntityItem::render(RenderArgs* args) {
|
||||||
static const int SLICES = 15, STACKS = 15;
|
static const int SLICES = 15, STACKS = 15;
|
||||||
|
|
||||||
if (!_procedural) {
|
if (!_procedural) {
|
||||||
_procedural.reset(new ProceduralInfo(this));
|
_procedural.reset(new Procedural(getUserData()));
|
||||||
|
_procedural->_vertexSource = simple_vert;
|
||||||
|
_procedural->_fragmentSource = simple_frag;
|
||||||
|
_procedural->_state->setCullMode(gpu::State::CULL_NONE);
|
||||||
|
_procedural->_state->setDepthTest(true, true, gpu::LESS_EQUAL);
|
||||||
|
_procedural->_state->setBlendFunction(false,
|
||||||
|
gpu::State::SRC_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::INV_SRC_ALPHA,
|
||||||
|
gpu::State::FACTOR_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::ONE);
|
||||||
}
|
}
|
||||||
|
|
||||||
glm::vec4 sphereColor(toGlm(getXColor()), getLocalRenderAlpha());
|
glm::vec4 sphereColor(toGlm(getXColor()), getLocalRenderAlpha());
|
||||||
if (_procedural->ready()) {
|
if (_procedural->ready()) {
|
||||||
_procedural->prepare(batch);
|
_procedural->prepare(batch, getDimensions());
|
||||||
DependencyManager::get<GeometryCache>()->renderSphere(batch, 0.5f, SLICES, STACKS, _procedural->getColor(sphereColor));
|
DependencyManager::get<GeometryCache>()->renderSphere(batch, 0.5f, SLICES, STACKS, _procedural->getColor(sphereColor));
|
||||||
} else {
|
} else {
|
||||||
DependencyManager::get<DeferredLightingEffect>()->renderSolidSphere(batch, 0.5f, SLICES, STACKS, sphereColor);
|
DependencyManager::get<DeferredLightingEffect>()->renderSolidSphere(batch, 0.5f, SLICES, STACKS, sphereColor);
|
||||||
|
|
|
@ -13,10 +13,11 @@
|
||||||
#define hifi_RenderableSphereEntityItem_h
|
#define hifi_RenderableSphereEntityItem_h
|
||||||
|
|
||||||
#include <SphereEntityItem.h>
|
#include <SphereEntityItem.h>
|
||||||
#include "RenderableEntityItem.h"
|
#include <procedural/Procedural.h>
|
||||||
#include "RenderableProceduralItem.h"
|
|
||||||
|
|
||||||
class RenderableSphereEntityItem : public SphereEntityItem, RenderableProceduralItem {
|
#include "RenderableEntityItem.h"
|
||||||
|
|
||||||
|
class RenderableSphereEntityItem : public SphereEntityItem {
|
||||||
public:
|
public:
|
||||||
static EntityItemPointer factory(const EntityItemID& entityID, const EntityItemProperties& properties);
|
static EntityItemPointer factory(const EntityItemID& entityID, const EntityItemProperties& properties);
|
||||||
|
|
||||||
|
@ -28,6 +29,9 @@ public:
|
||||||
virtual void setUserData(const QString& value);
|
virtual void setUserData(const QString& value);
|
||||||
|
|
||||||
SIMPLE_RENDERABLE();
|
SIMPLE_RENDERABLE();
|
||||||
|
|
||||||
|
private:
|
||||||
|
QSharedPointer<Procedural> _procedural;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
11
libraries/gpu-networking/CMakeLists.txt
Normal file
11
libraries/gpu-networking/CMakeLists.txt
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
set(TARGET_NAME gpu-networking)
|
||||||
|
|
||||||
|
# use setup_hifi_library macro to setup our project and link appropriate Qt modules
|
||||||
|
setup_hifi_library()
|
||||||
|
|
||||||
|
add_dependency_external_projects(glm)
|
||||||
|
find_package(GLM REQUIRED)
|
||||||
|
target_include_directories(${TARGET_NAME} PUBLIC ${GLM_INCLUDE_DIRS})
|
||||||
|
|
||||||
|
link_hifi_libraries(shared networking gpu)
|
||||||
|
|
|
@ -0,0 +1,11 @@
|
||||||
|
//
|
||||||
|
// Created by Bradley Austin Davis on 2015/08/07
|
||||||
|
// Copyright 2013-2015 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
|
||||||
|
//
|
||||||
|
|
||||||
|
#include "GpuNetworkingLogging.h"
|
||||||
|
|
||||||
|
Q_LOGGING_CATEGORY(gpunetwork, "hifi.gpu-network")
|
|
@ -0,0 +1,11 @@
|
||||||
|
//
|
||||||
|
// Created by Bradley Austin Davis on 2015/08/07
|
||||||
|
// Copyright 2013-2015 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
|
||||||
|
//
|
||||||
|
|
||||||
|
#include <QLoggingCategory>
|
||||||
|
|
||||||
|
Q_DECLARE_LOGGING_CATEGORY(gpunetwork)
|
|
@ -1,7 +1,4 @@
|
||||||
//
|
//
|
||||||
// TextureCache.cpp
|
|
||||||
// interface/src/renderer
|
|
||||||
//
|
|
||||||
// Created by Andrzej Kapolka on 8/6/13.
|
// Created by Andrzej Kapolka on 8/6/13.
|
||||||
// Copyright 2013 High Fidelity, Inc.
|
// Copyright 2013 High Fidelity, Inc.
|
||||||
//
|
//
|
||||||
|
@ -21,13 +18,11 @@
|
||||||
#include <QRunnable>
|
#include <QRunnable>
|
||||||
#include <QThreadPool>
|
#include <QThreadPool>
|
||||||
#include <qimagereader.h>
|
#include <qimagereader.h>
|
||||||
#include "PathUtils.h"
|
#include <PathUtils.h>
|
||||||
|
|
||||||
#include <gpu/Batch.h>
|
#include <gpu/Batch.h>
|
||||||
|
|
||||||
|
#include "GpuNetworkingLogging.h"
|
||||||
|
|
||||||
#include "RenderUtilsLogging.h"
|
|
||||||
|
|
||||||
TextureCache::TextureCache() {
|
TextureCache::TextureCache() {
|
||||||
const qint64 TEXTURE_DEFAULT_UNUSED_MAX_SIZE = DEFAULT_UNUSED_MAX_SIZE;
|
const qint64 TEXTURE_DEFAULT_UNUSED_MAX_SIZE = DEFAULT_UNUSED_MAX_SIZE;
|
||||||
|
@ -241,7 +236,9 @@ ImageReader::ImageReader(const QWeakPointer<Resource>& texture, TextureType type
|
||||||
_texture(texture),
|
_texture(texture),
|
||||||
_type(type),
|
_type(type),
|
||||||
_url(url),
|
_url(url),
|
||||||
_content(data) {
|
_content(data)
|
||||||
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::once_flag onceListSupportedFormatsflag;
|
std::once_flag onceListSupportedFormatsflag;
|
||||||
|
@ -252,7 +249,7 @@ void listSupportedImageFormats() {
|
||||||
foreach(const QByteArray& f, supportedFormats) {
|
foreach(const QByteArray& f, supportedFormats) {
|
||||||
formats += QString(f) + ",";
|
formats += QString(f) + ",";
|
||||||
}
|
}
|
||||||
qCDebug(renderutils) << "List of supported Image formats:" << formats;
|
qCDebug(gpunetwork) << "List of supported Image formats:" << formats;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -312,9 +309,9 @@ void ImageReader::run() {
|
||||||
|
|
||||||
if (originalWidth == 0 || originalHeight == 0 || imageFormat == QImage::Format_Invalid) {
|
if (originalWidth == 0 || originalHeight == 0 || imageFormat == QImage::Format_Invalid) {
|
||||||
if (filenameExtension.empty()) {
|
if (filenameExtension.empty()) {
|
||||||
qCDebug(renderutils) << "QImage failed to create from content, no file extension:" << _url;
|
qCDebug(gpunetwork) << "QImage failed to create from content, no file extension:" << _url;
|
||||||
} else {
|
} else {
|
||||||
qCDebug(renderutils) << "QImage failed to create from content" << _url;
|
qCDebug(gpunetwork) << "QImage failed to create from content" << _url;
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -322,7 +319,7 @@ void ImageReader::run() {
|
||||||
int imageArea = image.width() * image.height();
|
int imageArea = image.width() * image.height();
|
||||||
auto ntex = dynamic_cast<NetworkTexture*>(&*texture);
|
auto ntex = dynamic_cast<NetworkTexture*>(&*texture);
|
||||||
if (ntex && (ntex->getType() == CUBE_TEXTURE)) {
|
if (ntex && (ntex->getType() == CUBE_TEXTURE)) {
|
||||||
qCDebug(renderutils) << "Cube map size:" << _url << image.width() << image.height();
|
qCDebug(gpunetwork) << "Cube map size:" << _url << image.width() << image.height();
|
||||||
}
|
}
|
||||||
|
|
||||||
int opaquePixels = 0;
|
int opaquePixels = 0;
|
||||||
|
@ -373,7 +370,7 @@ void ImageReader::run() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (opaquePixels == imageArea) {
|
if (opaquePixels == imageArea) {
|
||||||
qCDebug(renderutils) << "Image with alpha channel is completely opaque:" << _url;
|
qCDebug(gpunetwork) << "Image with alpha channel is completely opaque:" << _url;
|
||||||
image = image.convertToFormat(QImage::Format_RGB888);
|
image = image.convertToFormat(QImage::Format_RGB888);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -521,7 +518,7 @@ void ImageReader::run() {
|
||||||
faces.push_back(image.copy(QRect(layout._faceZPos._x * faceWidth, layout._faceZPos._y * faceWidth, faceWidth, faceWidth)).mirrored(layout._faceZPos._horizontalMirror, layout._faceZPos._verticalMirror));
|
faces.push_back(image.copy(QRect(layout._faceZPos._x * faceWidth, layout._faceZPos._y * faceWidth, faceWidth, faceWidth)).mirrored(layout._faceZPos._horizontalMirror, layout._faceZPos._verticalMirror));
|
||||||
faces.push_back(image.copy(QRect(layout._faceZNeg._x * faceWidth, layout._faceZNeg._y * faceWidth, faceWidth, faceWidth)).mirrored(layout._faceZNeg._horizontalMirror, layout._faceZNeg._verticalMirror));
|
faces.push_back(image.copy(QRect(layout._faceZNeg._x * faceWidth, layout._faceZNeg._y * faceWidth, faceWidth, faceWidth)).mirrored(layout._faceZNeg._horizontalMirror, layout._faceZNeg._verticalMirror));
|
||||||
} else {
|
} else {
|
||||||
qCDebug(renderutils) << "Failed to find a known cube map layout from this image:" << _url;
|
qCDebug(gpunetwork) << "Failed to find a known cube map layout from this image:" << _url;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
167
libraries/gpu-networking/src/gpu-networking/TextureCache.h
Normal file
167
libraries/gpu-networking/src/gpu-networking/TextureCache.h
Normal file
|
@ -0,0 +1,167 @@
|
||||||
|
//
|
||||||
|
// Created by Andrzej Kapolka on 8/6/13.
|
||||||
|
// Copyright 2013 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
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef hifi_TextureCache_h
|
||||||
|
#define hifi_TextureCache_h
|
||||||
|
|
||||||
|
#include <gpu/Texture.h>
|
||||||
|
|
||||||
|
#include <QImage>
|
||||||
|
#include <QMap>
|
||||||
|
#include <QColor>
|
||||||
|
|
||||||
|
#include <DependencyManager.h>
|
||||||
|
#include <ResourceCache.h>
|
||||||
|
|
||||||
|
namespace gpu {
|
||||||
|
class Batch;
|
||||||
|
}
|
||||||
|
class NetworkTexture;
|
||||||
|
|
||||||
|
typedef QSharedPointer<NetworkTexture> NetworkTexturePointer;
|
||||||
|
|
||||||
|
enum TextureType { DEFAULT_TEXTURE, NORMAL_TEXTURE, SPECULAR_TEXTURE, EMISSIVE_TEXTURE, SPLAT_TEXTURE, CUBE_TEXTURE };
|
||||||
|
|
||||||
|
/// Stores cached textures, including render-to-texture targets.
|
||||||
|
class TextureCache : public ResourceCache, public Dependency {
|
||||||
|
Q_OBJECT
|
||||||
|
SINGLETON_DEPENDENCY
|
||||||
|
|
||||||
|
public:
|
||||||
|
/// Returns the ID of the permutation/normal texture used for Perlin noise shader programs. This texture
|
||||||
|
/// has two lines: the first, a set of random numbers in [0, 255] to be used as permutation offsets, and
|
||||||
|
/// the second, a set of random unit vectors to be used as noise gradients.
|
||||||
|
const gpu::TexturePointer& getPermutationNormalTexture();
|
||||||
|
|
||||||
|
/// Returns an opaque white texture (useful for a default).
|
||||||
|
const gpu::TexturePointer& getWhiteTexture();
|
||||||
|
|
||||||
|
/// Returns an opaque gray texture (useful for a default).
|
||||||
|
const gpu::TexturePointer& getGrayTexture();
|
||||||
|
|
||||||
|
/// Returns the a pale blue texture (useful for a normal map).
|
||||||
|
const gpu::TexturePointer& getBlueTexture();
|
||||||
|
|
||||||
|
/// Returns the a black texture (useful for a default).
|
||||||
|
const gpu::TexturePointer& getBlackTexture();
|
||||||
|
|
||||||
|
// Returns a map used to compress the normals through a fitting scale algorithm
|
||||||
|
const gpu::TexturePointer& getNormalFittingTexture();
|
||||||
|
|
||||||
|
/// Returns a texture version of an image file
|
||||||
|
static gpu::TexturePointer getImageTexture(const QString& path);
|
||||||
|
|
||||||
|
/// Loads a texture from the specified URL.
|
||||||
|
NetworkTexturePointer getTexture(const QUrl& url, TextureType type = DEFAULT_TEXTURE, bool dilatable = false,
|
||||||
|
const QByteArray& content = QByteArray());
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
virtual QSharedPointer<Resource> createResource(const QUrl& url,
|
||||||
|
const QSharedPointer<Resource>& fallback, bool delayLoad, const void* extra);
|
||||||
|
|
||||||
|
private:
|
||||||
|
TextureCache();
|
||||||
|
virtual ~TextureCache();
|
||||||
|
friend class DilatableNetworkTexture;
|
||||||
|
|
||||||
|
gpu::TexturePointer _permutationNormalTexture;
|
||||||
|
gpu::TexturePointer _whiteTexture;
|
||||||
|
gpu::TexturePointer _grayTexture;
|
||||||
|
gpu::TexturePointer _blueTexture;
|
||||||
|
gpu::TexturePointer _blackTexture;
|
||||||
|
gpu::TexturePointer _normalFittingTexture;
|
||||||
|
|
||||||
|
QHash<QUrl, QWeakPointer<NetworkTexture> > _dilatableNetworkTextures;
|
||||||
|
};
|
||||||
|
|
||||||
|
/// A simple object wrapper for an OpenGL texture.
|
||||||
|
class Texture {
|
||||||
|
public:
|
||||||
|
friend class TextureCache;
|
||||||
|
friend class DilatableNetworkTexture;
|
||||||
|
Texture();
|
||||||
|
~Texture();
|
||||||
|
|
||||||
|
const gpu::TexturePointer& getGPUTexture() const { return _gpuTexture; }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
gpu::TexturePointer _gpuTexture;
|
||||||
|
|
||||||
|
private:
|
||||||
|
};
|
||||||
|
|
||||||
|
/// A texture loaded from the network.
|
||||||
|
|
||||||
|
class NetworkTexture : public Resource, public Texture {
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
NetworkTexture(const QUrl& url, TextureType type, const QByteArray& content);
|
||||||
|
|
||||||
|
/// Checks whether it "looks like" this texture is translucent
|
||||||
|
/// (majority of pixels neither fully opaque or fully transparent).
|
||||||
|
bool isTranslucent() const { return _translucent; }
|
||||||
|
|
||||||
|
/// Returns the lazily-computed average texture color.
|
||||||
|
const QColor& getAverageColor() const { return _averageColor; }
|
||||||
|
|
||||||
|
int getOriginalWidth() const { return _originalWidth; }
|
||||||
|
int getOriginalHeight() const { return _originalHeight; }
|
||||||
|
int getWidth() const { return _width; }
|
||||||
|
int getHeight() const { return _height; }
|
||||||
|
TextureType getType() const { return _type; }
|
||||||
|
protected:
|
||||||
|
|
||||||
|
virtual void downloadFinished(const QByteArray& data) override;
|
||||||
|
|
||||||
|
Q_INVOKABLE void loadContent(const QByteArray& content);
|
||||||
|
// FIXME: This void* should be a gpu::Texture* but i cannot get it to work for now, moving on...
|
||||||
|
Q_INVOKABLE void setImage(const QImage& image, void* texture, bool translucent, const QColor& averageColor, int originalWidth,
|
||||||
|
int originalHeight);
|
||||||
|
|
||||||
|
virtual void imageLoaded(const QImage& image);
|
||||||
|
|
||||||
|
TextureType _type;
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool _translucent;
|
||||||
|
QColor _averageColor;
|
||||||
|
int _originalWidth;
|
||||||
|
int _originalHeight;
|
||||||
|
int _width;
|
||||||
|
int _height;
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Caches derived, dilated textures.
|
||||||
|
class DilatableNetworkTexture : public NetworkTexture {
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
DilatableNetworkTexture(const QUrl& url, const QByteArray& content);
|
||||||
|
|
||||||
|
/// Returns a pointer to a texture with the requested amount of dilation.
|
||||||
|
QSharedPointer<Texture> getDilatedTexture(float dilation);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
virtual void imageLoaded(const QImage& image);
|
||||||
|
virtual void reinsert();
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
QImage _image;
|
||||||
|
int _innerRadius;
|
||||||
|
int _outerRadius;
|
||||||
|
|
||||||
|
QMap<float, QWeakPointer<Texture> > _dilatedTextures;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // hifi_TextureCache_h
|
|
@ -7,6 +7,10 @@ setup_hifi_library()
|
||||||
|
|
||||||
link_hifi_libraries(shared)
|
link_hifi_libraries(shared)
|
||||||
|
|
||||||
|
add_dependency_external_projects(glm)
|
||||||
|
find_package(GLM REQUIRED)
|
||||||
|
target_include_directories(${TARGET_NAME} PUBLIC ${GLM_INCLUDE_DIRS})
|
||||||
|
|
||||||
add_dependency_external_projects(glew)
|
add_dependency_external_projects(glew)
|
||||||
find_package(GLEW REQUIRED)
|
find_package(GLEW REQUIRED)
|
||||||
add_definitions(-DGLEW_STATIC)
|
add_definitions(-DGLEW_STATIC)
|
||||||
|
|
|
@ -9,4 +9,4 @@ add_dependency_external_projects(glm)
|
||||||
find_package(GLM REQUIRED)
|
find_package(GLM REQUIRED)
|
||||||
target_include_directories(${TARGET_NAME} PUBLIC ${GLM_INCLUDE_DIRS})
|
target_include_directories(${TARGET_NAME} PUBLIC ${GLM_INCLUDE_DIRS})
|
||||||
|
|
||||||
link_hifi_libraries(shared gpu octree)
|
link_hifi_libraries(shared networking gpu gpu-networking procedural octree)
|
||||||
|
|
|
@ -10,10 +10,12 @@
|
||||||
//
|
//
|
||||||
#include "Skybox.h"
|
#include "Skybox.h"
|
||||||
|
|
||||||
#include "gpu/Batch.h"
|
|
||||||
#include "gpu/Context.h"
|
|
||||||
|
|
||||||
#include "ViewFrustum.h"
|
#include <gpu/Batch.h>
|
||||||
|
#include <gpu/Context.h>
|
||||||
|
#include <procedural/Procedural.h>
|
||||||
|
#include <ViewFrustum.h>
|
||||||
|
|
||||||
#include "Skybox_vert.h"
|
#include "Skybox_vert.h"
|
||||||
#include "Skybox_frag.h"
|
#include "Skybox_frag.h"
|
||||||
|
|
||||||
|
@ -38,19 +40,54 @@ void Skybox::setColor(const Color& color) {
|
||||||
_color = color;
|
_color = color;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Skybox::setProcedural(QSharedPointer<Procedural> procedural) {
|
||||||
|
_procedural = procedural;
|
||||||
|
if (_procedural) {
|
||||||
|
_procedural->_vertexSource = Skybox_vert;
|
||||||
|
_procedural->_fragmentSource = Skybox_frag;
|
||||||
|
// No pipeline state customization
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void Skybox::setCubemap(const gpu::TexturePointer& cubemap) {
|
void Skybox::setCubemap(const gpu::TexturePointer& cubemap) {
|
||||||
_cubemap = cubemap;
|
_cubemap = cubemap;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Skybox::render(gpu::Batch& batch, const ViewFrustum& viewFrustum, const Skybox& skybox) {
|
void Skybox::render(gpu::Batch& batch, const ViewFrustum& viewFrustum, const Skybox& skybox) {
|
||||||
|
static gpu::BufferPointer theBuffer;
|
||||||
|
static gpu::Stream::FormatPointer theFormat;
|
||||||
|
|
||||||
if (skybox.getCubemap()) {
|
if (skybox._procedural || skybox.getCubemap()) {
|
||||||
if (skybox.getCubemap()->isDefined()) {
|
if (!theBuffer) {
|
||||||
|
const float CLIP = 1.0f;
|
||||||
|
const glm::vec2 vertices[4] = { { -CLIP, -CLIP }, { CLIP, -CLIP }, { -CLIP, CLIP }, { CLIP, CLIP } };
|
||||||
|
theBuffer = std::make_shared<gpu::Buffer>(sizeof(vertices), (const gpu::Byte*) vertices);
|
||||||
|
theFormat = std::make_shared<gpu::Stream::Format>();
|
||||||
|
theFormat->setAttribute(gpu::Stream::POSITION, gpu::Stream::POSITION, gpu::Element(gpu::VEC2, gpu::FLOAT, gpu::XYZ));
|
||||||
|
}
|
||||||
|
|
||||||
static gpu::PipelinePointer thePipeline;
|
glm::mat4 projMat;
|
||||||
static gpu::BufferPointer theBuffer;
|
viewFrustum.evalProjectionMatrix(projMat);
|
||||||
static gpu::Stream::FormatPointer theFormat;
|
|
||||||
|
Transform viewTransform;
|
||||||
|
viewFrustum.evalViewTransform(viewTransform);
|
||||||
|
batch.setProjectionTransform(projMat);
|
||||||
|
batch.setViewTransform(viewTransform);
|
||||||
|
batch.setModelTransform(Transform()); // only for Mac
|
||||||
|
batch.setInputBuffer(gpu::Stream::POSITION, theBuffer, 0, 8);
|
||||||
|
batch.setInputFormat(theFormat);
|
||||||
|
|
||||||
|
if (skybox._procedural && skybox._procedural->_enabled && skybox._procedural->ready()) {
|
||||||
|
if (skybox.getCubemap() && skybox.getCubemap()->isDefined()) {
|
||||||
|
batch.setResourceTexture(0, skybox.getCubemap());
|
||||||
|
}
|
||||||
|
|
||||||
|
skybox._procedural->prepare(batch, glm::vec3(1));
|
||||||
|
batch.draw(gpu::TRIANGLE_STRIP, 4);
|
||||||
|
} else if (skybox.getCubemap() && skybox.getCubemap()->isDefined()) {
|
||||||
static gpu::BufferPointer theConstants;
|
static gpu::BufferPointer theConstants;
|
||||||
|
static gpu::PipelinePointer thePipeline;
|
||||||
static int SKYBOX_CONSTANTS_SLOT = 0; // need to be defined by the compilation of the shader
|
static int SKYBOX_CONSTANTS_SLOT = 0; // need to be defined by the compilation of the shader
|
||||||
if (!thePipeline) {
|
if (!thePipeline) {
|
||||||
auto skyVS = gpu::ShaderPointer(gpu::Shader::createVertex(std::string(Skybox_vert)));
|
auto skyVS = gpu::ShaderPointer(gpu::Shader::createVertex(std::string(Skybox_vert)));
|
||||||
|
@ -72,23 +109,10 @@ void Skybox::render(gpu::Batch& batch, const ViewFrustum& viewFrustum, const Sky
|
||||||
|
|
||||||
thePipeline = gpu::PipelinePointer(gpu::Pipeline::create(skyShader, skyState));
|
thePipeline = gpu::PipelinePointer(gpu::Pipeline::create(skyShader, skyState));
|
||||||
|
|
||||||
const float CLIP = 1.0f;
|
|
||||||
const glm::vec2 vertices[4] = { {-CLIP, -CLIP}, {CLIP, -CLIP}, {-CLIP, CLIP}, {CLIP, CLIP}};
|
|
||||||
theBuffer = std::make_shared<gpu::Buffer>(sizeof(vertices), (const gpu::Byte*) vertices);
|
|
||||||
|
|
||||||
theFormat = std::make_shared<gpu::Stream::Format>();
|
|
||||||
theFormat->setAttribute(gpu::Stream::POSITION, gpu::Stream::POSITION, gpu::Element(gpu::VEC2, gpu::FLOAT, gpu::XYZ));
|
|
||||||
|
|
||||||
auto color = glm::vec4(1.0f);
|
auto color = glm::vec4(1.0f);
|
||||||
theConstants = std::make_shared<gpu::Buffer>(sizeof(color), (const gpu::Byte*) &color);
|
theConstants = std::make_shared<gpu::Buffer>(sizeof(color), (const gpu::Byte*) &color);
|
||||||
}
|
}
|
||||||
|
|
||||||
glm::mat4 projMat;
|
|
||||||
viewFrustum.evalProjectionMatrix(projMat);
|
|
||||||
|
|
||||||
Transform viewTransform;
|
|
||||||
viewFrustum.evalViewTransform(viewTransform);
|
|
||||||
|
|
||||||
if (glm::all(glm::equal(skybox.getColor(), glm::vec3(0.0f)))) {
|
if (glm::all(glm::equal(skybox.getColor(), glm::vec3(0.0f)))) {
|
||||||
auto color = glm::vec4(1.0f);
|
auto color = glm::vec4(1.0f);
|
||||||
theConstants->setSubData(0, sizeof(color), (const gpu::Byte*) &color);
|
theConstants->setSubData(0, sizeof(color), (const gpu::Byte*) &color);
|
||||||
|
@ -96,13 +120,8 @@ void Skybox::render(gpu::Batch& batch, const ViewFrustum& viewFrustum, const Sky
|
||||||
theConstants->setSubData(0, sizeof(Color), (const gpu::Byte*) &skybox.getColor());
|
theConstants->setSubData(0, sizeof(Color), (const gpu::Byte*) &skybox.getColor());
|
||||||
}
|
}
|
||||||
|
|
||||||
batch.setProjectionTransform(projMat);
|
|
||||||
batch.setViewTransform(viewTransform);
|
|
||||||
batch.setModelTransform(Transform()); // only for Mac
|
|
||||||
batch.setPipeline(thePipeline);
|
batch.setPipeline(thePipeline);
|
||||||
batch.setInputBuffer(gpu::Stream::POSITION, theBuffer, 0, 8);
|
|
||||||
batch.setUniformBuffer(SKYBOX_CONSTANTS_SLOT, theConstants, 0, theConstants->getSize());
|
batch.setUniformBuffer(SKYBOX_CONSTANTS_SLOT, theConstants, 0, theConstants->getSize());
|
||||||
batch.setInputFormat(theFormat);
|
|
||||||
batch.setResourceTexture(0, skybox.getCubemap());
|
batch.setResourceTexture(0, skybox.getCubemap());
|
||||||
batch.draw(gpu::TRIANGLE_STRIP, 4);
|
batch.draw(gpu::TRIANGLE_STRIP, 4);
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,12 +11,13 @@
|
||||||
#ifndef hifi_model_Skybox_h
|
#ifndef hifi_model_Skybox_h
|
||||||
#define hifi_model_Skybox_h
|
#define hifi_model_Skybox_h
|
||||||
|
|
||||||
#include "gpu/Texture.h"
|
#include <QtCore/QSharedPointer>
|
||||||
|
#include <gpu/Texture.h>
|
||||||
|
|
||||||
#include "Light.h"
|
#include "Light.h"
|
||||||
|
|
||||||
class ViewFrustum;
|
class ViewFrustum;
|
||||||
//class Transform;
|
struct Procedural;
|
||||||
namespace gpu { class Batch; }
|
namespace gpu { class Batch; }
|
||||||
|
|
||||||
namespace model {
|
namespace model {
|
||||||
|
@ -35,11 +36,13 @@ public:
|
||||||
void setCubemap(const gpu::TexturePointer& cubemap);
|
void setCubemap(const gpu::TexturePointer& cubemap);
|
||||||
const gpu::TexturePointer& getCubemap() const { return _cubemap; }
|
const gpu::TexturePointer& getCubemap() const { return _cubemap; }
|
||||||
|
|
||||||
|
void setProcedural(QSharedPointer<Procedural> procedural);
|
||||||
|
|
||||||
static void render(gpu::Batch& batch, const ViewFrustum& frustum, const Skybox& skybox);
|
static void render(gpu::Batch& batch, const ViewFrustum& frustum, const Skybox& skybox);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
gpu::TexturePointer _cubemap;
|
gpu::TexturePointer _cubemap;
|
||||||
|
QSharedPointer<Procedural> _procedural;
|
||||||
Color _color{1.0f, 1.0f, 1.0f};
|
Color _color{1.0f, 1.0f, 1.0f};
|
||||||
};
|
};
|
||||||
typedef std::shared_ptr< Skybox > SkyboxPointer;
|
typedef std::shared_ptr< Skybox > SkyboxPointer;
|
||||||
|
|
|
@ -22,13 +22,29 @@ uniform skyboxBuffer {
|
||||||
};
|
};
|
||||||
|
|
||||||
in vec3 _normal;
|
in vec3 _normal;
|
||||||
|
|
||||||
out vec4 _fragColor;
|
out vec4 _fragColor;
|
||||||
|
|
||||||
|
//PROCEDURAL_COMMON_BLOCK
|
||||||
|
|
||||||
|
#line 1001
|
||||||
|
//PROCEDURAL_BLOCK
|
||||||
|
|
||||||
|
#line 2033
|
||||||
void main(void) {
|
void main(void) {
|
||||||
|
|
||||||
|
#ifdef PROCEDURAL
|
||||||
|
|
||||||
|
vec3 color = getSkyboxColor();
|
||||||
|
_fragColor = vec4(color, 0.0);
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
vec3 coord = normalize(_normal);
|
vec3 coord = normalize(_normal);
|
||||||
vec3 texel = texture(cubeMap, coord).rgb;
|
vec3 texel = texture(cubeMap, coord).rgb;
|
||||||
vec3 color = texel * _skybox._color.rgb;
|
vec3 color = texel * _skybox._color.rgb;
|
||||||
vec3 pixel = pow(color, vec3(1.0/2.2)); // manual Gamma correction
|
vec3 pixel = pow(color, vec3(1.0/2.2)); // manual Gamma correction
|
||||||
_fragColor = vec4(pixel, 0.0);
|
_fragColor = vec4(pixel, 0.0);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
10
libraries/procedural/CMakeLists.txt
Normal file
10
libraries/procedural/CMakeLists.txt
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
set(TARGET_NAME procedural)
|
||||||
|
|
||||||
|
# use setup_hifi_library macro to setup our project and link appropriate Qt modules
|
||||||
|
setup_hifi_library()
|
||||||
|
|
||||||
|
add_dependency_external_projects(glm)
|
||||||
|
find_package(GLM REQUIRED)
|
||||||
|
target_include_directories(${TARGET_NAME} PUBLIC ${GLM_INCLUDE_DIRS})
|
||||||
|
|
||||||
|
link_hifi_libraries(shared gpu networking gpu-networking)
|
|
@ -6,7 +6,7 @@
|
||||||
// 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 "RenderableProceduralItem.h"
|
#include "Procedural.h"
|
||||||
|
|
||||||
#include <QtCore/QFile>
|
#include <QtCore/QFile>
|
||||||
#include <QtCore/QFileInfo>
|
#include <QtCore/QFileInfo>
|
||||||
|
@ -14,14 +14,12 @@
|
||||||
#include <QtCore/QJsonDocument>
|
#include <QtCore/QJsonDocument>
|
||||||
#include <QtCore/QJsonObject>
|
#include <QtCore/QJsonObject>
|
||||||
|
|
||||||
#include <ShaderCache.h>
|
#include <gpu-networking/ShaderCache.h>
|
||||||
#include <EntityItem.h>
|
|
||||||
#include <TextureCache.h>
|
|
||||||
#include <DeferredLightingEffect.h>
|
|
||||||
#include <gpu/Batch.h>
|
#include <gpu/Batch.h>
|
||||||
|
#include <SharedUtil.h>
|
||||||
|
#include <NumericalConstants.h>
|
||||||
|
|
||||||
#include "RenderableProceduralItemShader.h"
|
#include "ProceduralShaders.h"
|
||||||
#include "../render-utils/simple_vert.h"
|
|
||||||
|
|
||||||
static const char* const UNIFORM_TIME_NAME= "iGlobalTime";
|
static const char* const UNIFORM_TIME_NAME= "iGlobalTime";
|
||||||
static const char* const UNIFORM_SCALE_NAME = "iWorldScale";
|
static const char* const UNIFORM_SCALE_NAME = "iWorldScale";
|
||||||
|
@ -30,43 +28,46 @@ static const QString PROCEDURAL_USER_DATA_KEY = "ProceduralEntity";
|
||||||
static const QString URL_KEY = "shaderUrl";
|
static const QString URL_KEY = "shaderUrl";
|
||||||
static const QString VERSION_KEY = "version";
|
static const QString VERSION_KEY = "version";
|
||||||
static const QString UNIFORMS_KEY = "uniforms";
|
static const QString UNIFORMS_KEY = "uniforms";
|
||||||
|
static const std::string PROCEDURAL_BLOCK = "//PROCEDURAL_BLOCK";
|
||||||
|
static const std::string PROCEDURAL_COMMON_BLOCK = "//PROCEDURAL_COMMON_BLOCK";
|
||||||
|
static const std::string PROCEDURAL_VERSION = "//PROCEDURAL_VERSION";
|
||||||
|
|
||||||
RenderableProceduralItem::ProceduralInfo::ProceduralInfo(EntityItem* entity) : _entity(entity) {
|
|
||||||
parse();
|
// Example
|
||||||
|
//{
|
||||||
|
// "ProceduralEntity": {
|
||||||
|
// "shaderUrl": "file:///C:/Users/bdavis/Git/hifi/examples/shaders/test.fs",
|
||||||
|
// }
|
||||||
|
//}
|
||||||
|
QJsonValue Procedural::getProceduralData(const QString& proceduralJson) {
|
||||||
|
if (proceduralJson.isEmpty()) {
|
||||||
|
return QJsonValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
QJsonParseError parseError;
|
||||||
|
auto doc = QJsonDocument::fromJson(proceduralJson.toUtf8(), &parseError);
|
||||||
|
if (parseError.error != QJsonParseError::NoError) {
|
||||||
|
return QJsonValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
return doc.object()[PROCEDURAL_USER_DATA_KEY];
|
||||||
}
|
}
|
||||||
|
|
||||||
void RenderableProceduralItem::ProceduralInfo::parse() {
|
|
||||||
|
Procedural::Procedural(const QString& userDataJson) {
|
||||||
|
parse(userDataJson);
|
||||||
|
_state = std::make_shared<gpu::State>();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Procedural::parse(const QString& userDataJson) {
|
||||||
_enabled = false;
|
_enabled = false;
|
||||||
QJsonObject userData;
|
auto proceduralData = getProceduralData(userDataJson);
|
||||||
{
|
if (proceduralData.isObject()) {
|
||||||
const QString& userDataJson = _entity->getUserData();
|
parse(proceduralData.toObject());
|
||||||
if (userDataJson.isEmpty()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
QJsonParseError parseError;
|
|
||||||
auto doc = QJsonDocument::fromJson(userDataJson.toUtf8(), &parseError);
|
|
||||||
if (parseError.error != QJsonParseError::NoError) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
userData = doc.object();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Example
|
|
||||||
//{
|
|
||||||
// "ProceduralEntity": {
|
|
||||||
// "shaderUrl": "file:///C:/Users/bdavis/Git/hifi/examples/shaders/test.fs",
|
|
||||||
// "color" : "#FFFFFF"
|
|
||||||
// }
|
|
||||||
//}
|
|
||||||
auto proceduralData = userData[PROCEDURAL_USER_DATA_KEY];
|
|
||||||
if (proceduralData.isNull()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
parse(proceduralData.toObject());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void RenderableProceduralItem::ProceduralInfo::parse(const QJsonObject& proceduralData) {
|
void Procedural::parse(const QJsonObject& proceduralData) {
|
||||||
// grab the version number
|
// grab the version number
|
||||||
{
|
{
|
||||||
auto version = proceduralData[VERSION_KEY];
|
auto version = proceduralData[VERSION_KEY];
|
||||||
|
@ -106,7 +107,7 @@ void RenderableProceduralItem::ProceduralInfo::parse(const QJsonObject& procedur
|
||||||
_enabled = true;
|
_enabled = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool RenderableProceduralItem::ProceduralInfo::ready() {
|
bool Procedural::ready() {
|
||||||
if (!_enabled) {
|
if (!_enabled) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -122,7 +123,7 @@ bool RenderableProceduralItem::ProceduralInfo::ready() {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void RenderableProceduralItem::ProceduralInfo::prepare(gpu::Batch& batch) {
|
void Procedural::prepare(gpu::Batch& batch, const glm::vec3& size) {
|
||||||
if (_shaderUrl.isLocalFile()) {
|
if (_shaderUrl.isLocalFile()) {
|
||||||
auto lastModified = (quint64) QFileInfo(_shaderPath).lastModified().toMSecsSinceEpoch();
|
auto lastModified = (quint64) QFileInfo(_shaderPath).lastModified().toMSecsSinceEpoch();
|
||||||
if (lastModified > _shaderModified) {
|
if (lastModified > _shaderModified) {
|
||||||
|
@ -139,31 +140,33 @@ void RenderableProceduralItem::ProceduralInfo::prepare(gpu::Batch& batch) {
|
||||||
if (!_pipeline || _pipelineDirty) {
|
if (!_pipeline || _pipelineDirty) {
|
||||||
_pipelineDirty = true;
|
_pipelineDirty = true;
|
||||||
if (!_vertexShader) {
|
if (!_vertexShader) {
|
||||||
_vertexShader = gpu::ShaderPointer(gpu::Shader::createVertex(std::string(simple_vert)));
|
_vertexShader = gpu::ShaderPointer(gpu::Shader::createVertex(_vertexSource));
|
||||||
}
|
}
|
||||||
QString framentShaderSource;
|
|
||||||
switch (_version) {
|
|
||||||
case 1:
|
|
||||||
framentShaderSource = SHADER_TEMPLATE_V1.arg(_shaderSource);
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
// Build the fragment shader
|
||||||
case 2:
|
std::string fragmentShaderSource = _fragmentSource;
|
||||||
framentShaderSource = SHADER_TEMPLATE_V2.arg(_shaderSource);
|
size_t replaceIndex = fragmentShaderSource.find(PROCEDURAL_COMMON_BLOCK);
|
||||||
break;
|
if (replaceIndex != std::string::npos) {
|
||||||
|
fragmentShaderSource.replace(replaceIndex, PROCEDURAL_COMMON_BLOCK.size(), SHADER_COMMON);
|
||||||
}
|
}
|
||||||
_fragmentShader = gpu::ShaderPointer(gpu::Shader::createPixel(std::string(framentShaderSource.toLocal8Bit().data())));
|
|
||||||
|
replaceIndex = fragmentShaderSource.find(PROCEDURAL_VERSION);
|
||||||
|
if (replaceIndex != std::string::npos) {
|
||||||
|
if (_version == 1) {
|
||||||
|
fragmentShaderSource.replace(replaceIndex, PROCEDURAL_VERSION.size(), "#define PROCEDURAL_V1 1");
|
||||||
|
} else if (_version == 2) {
|
||||||
|
fragmentShaderSource.replace(replaceIndex, PROCEDURAL_VERSION.size(), "#define PROCEDURAL_V2 1");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
replaceIndex = fragmentShaderSource.find(PROCEDURAL_BLOCK);
|
||||||
|
if (replaceIndex != std::string::npos) {
|
||||||
|
fragmentShaderSource.replace(replaceIndex, PROCEDURAL_BLOCK.size(), _shaderSource.toLocal8Bit().data());
|
||||||
|
}
|
||||||
|
qDebug() << "FragmentShader:\n" << fragmentShaderSource.c_str();
|
||||||
|
_fragmentShader = gpu::ShaderPointer(gpu::Shader::createPixel(fragmentShaderSource));
|
||||||
_shader = gpu::ShaderPointer(gpu::Shader::createProgram(_vertexShader, _fragmentShader));
|
_shader = gpu::ShaderPointer(gpu::Shader::createProgram(_vertexShader, _fragmentShader));
|
||||||
gpu::Shader::BindingSet slotBindings;
|
gpu::Shader::makeProgram(*_shader);
|
||||||
slotBindings.insert(gpu::Shader::Binding(std::string("normalFittingMap"), DeferredLightingEffect::NORMAL_FITTING_MAP_SLOT));
|
_pipeline = gpu::PipelinePointer(gpu::Pipeline::create(_shader, _state));
|
||||||
gpu::Shader::makeProgram(*_shader, slotBindings);
|
|
||||||
auto state = std::make_shared<gpu::State>();
|
|
||||||
state->setCullMode(gpu::State::CULL_NONE);
|
|
||||||
state->setDepthTest(true, true, gpu::LESS_EQUAL);
|
|
||||||
state->setBlendFunction(false,
|
|
||||||
gpu::State::SRC_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::INV_SRC_ALPHA,
|
|
||||||
gpu::State::FACTOR_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::ONE);
|
|
||||||
_pipeline = gpu::PipelinePointer(gpu::Pipeline::create(_shader, state));
|
|
||||||
_timeSlot = _shader->getUniforms().findLocation(UNIFORM_TIME_NAME);
|
_timeSlot = _shader->getUniforms().findLocation(UNIFORM_TIME_NAME);
|
||||||
_scaleSlot = _shader->getUniforms().findLocation(UNIFORM_SCALE_NAME);
|
_scaleSlot = _shader->getUniforms().findLocation(UNIFORM_SCALE_NAME);
|
||||||
_start = usecTimestampNow();
|
_start = usecTimestampNow();
|
||||||
|
@ -221,15 +224,12 @@ void RenderableProceduralItem::ProceduralInfo::prepare(gpu::Batch& batch) {
|
||||||
// Minimize floating point error by doing an integer division to milliseconds, before the floating point division to seconds
|
// Minimize floating point error by doing an integer division to milliseconds, before the floating point division to seconds
|
||||||
float time = (float)((usecTimestampNow() - _start) / USECS_PER_MSEC) / MSECS_PER_SECOND;
|
float time = (float)((usecTimestampNow() - _start) / USECS_PER_MSEC) / MSECS_PER_SECOND;
|
||||||
batch._glUniform1f(_timeSlot, time);
|
batch._glUniform1f(_timeSlot, time);
|
||||||
|
|
||||||
// FIXME move into the 'set once' section, since this doesn't change over time
|
// FIXME move into the 'set once' section, since this doesn't change over time
|
||||||
auto scale = _entity->getDimensions();
|
batch._glUniform3f(_scaleSlot, size.x, size.y, size.z);
|
||||||
batch._glUniform3f(_scaleSlot, scale.x, scale.y, scale.z);
|
|
||||||
batch.setResourceTexture(DeferredLightingEffect::NORMAL_FITTING_MAP_SLOT, DependencyManager::get<TextureCache>()->getNormalFittingTexture());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
glm::vec4 RenderableProceduralItem::ProceduralInfo::getColor(const glm::vec4& entityColor) {
|
glm::vec4 Procedural::getColor(const glm::vec4& entityColor) {
|
||||||
if (_version == 1) {
|
if (_version == 1) {
|
||||||
return glm::vec4(1);
|
return glm::vec4(1);
|
||||||
}
|
}
|
60
libraries/procedural/src/procedural/Procedural.h
Normal file
60
libraries/procedural/src/procedural/Procedural.h
Normal file
|
@ -0,0 +1,60 @@
|
||||||
|
//
|
||||||
|
// Created by Bradley Austin Davis on 2015/09/05
|
||||||
|
// Copyright 2013-2015 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
|
||||||
|
//
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
#ifndef hifi_RenderableProcedrualItem_h
|
||||||
|
#define hifi_RenderableProcedrualItem_h
|
||||||
|
|
||||||
|
#include <QtCore/qglobal.h>
|
||||||
|
#include <QtCore/QString>
|
||||||
|
#include <QtCore/QUrl>
|
||||||
|
#include <QtCore/QJsonObject>
|
||||||
|
|
||||||
|
#include <gpu/Shader.h>
|
||||||
|
#include <gpu/Pipeline.h>
|
||||||
|
#include <gpu/Batch.h>
|
||||||
|
#include <gpu-networking/ShaderCache.h>
|
||||||
|
|
||||||
|
|
||||||
|
// FIXME better encapsulation
|
||||||
|
// FIXME better mechanism for extending to things rendered using shaders other than simple.slv
|
||||||
|
struct Procedural {
|
||||||
|
static QJsonValue getProceduralData(const QString& proceduralJson);
|
||||||
|
|
||||||
|
Procedural(const QString& userDataJson);
|
||||||
|
void parse(const QString& userDataJson);
|
||||||
|
void parse(const QJsonObject&);
|
||||||
|
bool ready();
|
||||||
|
void prepare(gpu::Batch& batch, const glm::vec3& size);
|
||||||
|
glm::vec4 getColor(const glm::vec4& entityColor);
|
||||||
|
|
||||||
|
bool _enabled{ false };
|
||||||
|
uint8_t _version{ 1 };
|
||||||
|
|
||||||
|
std::string _vertexSource;
|
||||||
|
std::string _fragmentSource;
|
||||||
|
|
||||||
|
QString _shaderSource;
|
||||||
|
QString _shaderPath;
|
||||||
|
QUrl _shaderUrl;
|
||||||
|
quint64 _shaderModified{ 0 };
|
||||||
|
bool _pipelineDirty{ true };
|
||||||
|
int32_t _timeSlot{ gpu::Shader::INVALID_LOCATION };
|
||||||
|
int32_t _scaleSlot{ gpu::Shader::INVALID_LOCATION };
|
||||||
|
uint64_t _start{ 0 };
|
||||||
|
NetworkShaderPointer _networkShader;
|
||||||
|
QJsonObject _uniforms;
|
||||||
|
|
||||||
|
gpu::PipelinePointer _pipeline;
|
||||||
|
gpu::ShaderPointer _vertexShader;
|
||||||
|
gpu::ShaderPointer _fragmentShader;
|
||||||
|
gpu::ShaderPointer _shader;
|
||||||
|
gpu::StatePointer _state;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
276
libraries/procedural/src/procedural/ProceduralShaders.h
Normal file
276
libraries/procedural/src/procedural/ProceduralShaders.h
Normal file
|
@ -0,0 +1,276 @@
|
||||||
|
//
|
||||||
|
// Created by Bradley Austin Davis on 2015/09/05
|
||||||
|
// Copyright 2013-2015 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
|
||||||
|
//
|
||||||
|
|
||||||
|
// Shader includes portions of webgl-noise:
|
||||||
|
// Description : Array and textureless GLSL 2D/3D/4D simplex
|
||||||
|
// noise functions.
|
||||||
|
// Author : Ian McEwan, Ashima Arts.
|
||||||
|
// Maintainer : ijm
|
||||||
|
// Lastmod : 20110822 (ijm)
|
||||||
|
// License : Copyright (C) 2011 Ashima Arts. All rights reserved.
|
||||||
|
// Distributed under the MIT License. See LICENSE file.
|
||||||
|
// https://github.com/ashima/webgl-noise
|
||||||
|
//
|
||||||
|
|
||||||
|
|
||||||
|
const std::string SHADER_COMMON = R"SHADER(
|
||||||
|
|
||||||
|
float mod289(float x) {
|
||||||
|
return x - floor(x * (1.0 / 289.0)) * 289.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
vec2 mod289(vec2 x) {
|
||||||
|
return x - floor(x * (1.0 / 289.0)) * 289.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
vec3 mod289(vec3 x) {
|
||||||
|
return x - floor(x * (1.0 / 289.0)) * 289.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
vec4 mod289(vec4 x) {
|
||||||
|
return x - floor(x * (1.0 / 289.0)) * 289.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
float permute(float x) {
|
||||||
|
return mod289(((x*34.0)+1.0)*x);
|
||||||
|
}
|
||||||
|
|
||||||
|
vec3 permute(vec3 x) {
|
||||||
|
return mod289(((x*34.0)+1.0)*x);
|
||||||
|
}
|
||||||
|
|
||||||
|
vec4 permute(vec4 x) {
|
||||||
|
return mod289(((x*34.0)+1.0)*x);
|
||||||
|
}
|
||||||
|
|
||||||
|
float taylorInvSqrt(float r) {
|
||||||
|
return 1.79284291400159 - 0.85373472095314 * r;
|
||||||
|
}
|
||||||
|
|
||||||
|
vec4 taylorInvSqrt(vec4 r) {
|
||||||
|
return 1.79284291400159 - 0.85373472095314 * r;
|
||||||
|
}
|
||||||
|
|
||||||
|
vec4 grad4(float j, vec4 ip) {
|
||||||
|
const vec4 ones = vec4(1.0, 1.0, 1.0, -1.0);
|
||||||
|
vec4 p, s;
|
||||||
|
|
||||||
|
p.xyz = floor(fract(vec3(j) * ip.xyz) * 7.0) * ip.z - 1.0;
|
||||||
|
p.w = 1.5 - dot(abs(p.xyz), ones.xyz);
|
||||||
|
s = vec4(lessThan(p, vec4(0.0)));
|
||||||
|
p.xyz = p.xyz + (s.xyz * 2.0 - 1.0) * s.www;
|
||||||
|
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
|
// (sqrt(5) - 1)/4 = F4, used once below
|
||||||
|
#define F4 0.309016994374947451
|
||||||
|
|
||||||
|
float snoise(vec4 v) {
|
||||||
|
const vec4 C = vec4(0.138196601125011, // (5 - sqrt(5))/20 G4
|
||||||
|
0.276393202250021, // 2 * G4
|
||||||
|
0.414589803375032, // 3 * G4
|
||||||
|
-0.447213595499958); // -1 + 4 * G4
|
||||||
|
|
||||||
|
// First corner
|
||||||
|
vec4 i = floor(v + dot(v, vec4(F4)));
|
||||||
|
vec4 x0 = v - i + dot(i, C.xxxx);
|
||||||
|
|
||||||
|
// Other corners
|
||||||
|
|
||||||
|
// Rank sorting originally contributed by Bill Licea-Kane, AMD (formerly ATI)
|
||||||
|
vec4 i0;
|
||||||
|
vec3 isX = step(x0.yzw, x0.xxx);
|
||||||
|
vec3 isYZ = step(x0.zww, x0.yyz);
|
||||||
|
i0.x = isX.x + isX.y + isX.z;
|
||||||
|
i0.yzw = 1.0 - isX;
|
||||||
|
i0.y += isYZ.x + isYZ.y;
|
||||||
|
i0.zw += 1.0 - isYZ.xy;
|
||||||
|
i0.z += isYZ.z;
|
||||||
|
i0.w += 1.0 - isYZ.z;
|
||||||
|
|
||||||
|
// i0 now contains the unique values 0,1,2,3 in each channel
|
||||||
|
vec4 i3 = clamp(i0, 0.0, 1.0);
|
||||||
|
vec4 i2 = clamp(i0 - 1.0, 0.0, 1.0);
|
||||||
|
vec4 i1 = clamp(i0 - 2.0, 0.0, 1.0);
|
||||||
|
|
||||||
|
vec4 x1 = x0 - i1 + C.xxxx;
|
||||||
|
vec4 x2 = x0 - i2 + C.yyyy;
|
||||||
|
vec4 x3 = x0 - i3 + C.zzzz;
|
||||||
|
vec4 x4 = x0 + C.wwww;
|
||||||
|
|
||||||
|
// Permutations
|
||||||
|
i = mod289(i);
|
||||||
|
float j0 = permute(permute(permute(permute(i.w) + i.z) + i.y) + i.x);
|
||||||
|
vec4 j1 = permute(
|
||||||
|
permute(
|
||||||
|
permute(
|
||||||
|
permute(i.w + vec4(i1.w, i2.w, i3.w, 1.0)) + i.z
|
||||||
|
+ vec4(i1.z, i2.z, i3.z, 1.0)) + i.y
|
||||||
|
+ vec4(i1.y, i2.y, i3.y, 1.0)) + i.x
|
||||||
|
+ vec4(i1.x, i2.x, i3.x, 1.0));
|
||||||
|
|
||||||
|
// Gradients: 7x7x6 points over a cube, mapped onto a 4-cross polytope
|
||||||
|
// 7*7*6 = 294, which is close to the ring size 17*17 = 289.
|
||||||
|
vec4 ip = vec4(1.0 / 294.0, 1.0 / 49.0, 1.0 / 7.0, 0.0);
|
||||||
|
|
||||||
|
vec4 p0 = grad4(j0, ip);
|
||||||
|
vec4 p1 = grad4(j1.x, ip);
|
||||||
|
vec4 p2 = grad4(j1.y, ip);
|
||||||
|
vec4 p3 = grad4(j1.z, ip);
|
||||||
|
vec4 p4 = grad4(j1.w, ip);
|
||||||
|
|
||||||
|
// Normalise gradients
|
||||||
|
vec4 norm = taylorInvSqrt(
|
||||||
|
vec4(dot(p0, p0), dot(p1, p1), dot(p2, p2), dot(p3, p3)));
|
||||||
|
p0 *= norm.x;
|
||||||
|
p1 *= norm.y;
|
||||||
|
p2 *= norm.z;
|
||||||
|
p3 *= norm.w;
|
||||||
|
p4 *= taylorInvSqrt(dot(p4, p4));
|
||||||
|
|
||||||
|
// Mix contributions from the five corners
|
||||||
|
vec3 m0 = max(0.6 - vec3(dot(x0, x0), dot(x1, x1), dot(x2, x2)), 0.0);
|
||||||
|
vec2 m1 = max(0.6 - vec2(dot(x3, x3), dot(x4, x4)), 0.0);
|
||||||
|
m0 = m0 * m0;
|
||||||
|
m1 = m1 * m1;
|
||||||
|
return 49.0
|
||||||
|
* (dot(m0 * m0, vec3(dot(p0, x0), dot(p1, x1), dot(p2, x2)))
|
||||||
|
+ dot(m1 * m1, vec2(dot(p3, x3), dot(p4, x4))));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
float snoise(vec3 v) {
|
||||||
|
const vec2 C = vec2(1.0 / 6.0, 1.0 / 3.0);
|
||||||
|
const vec4 D = vec4(0.0, 0.5, 1.0, 2.0);
|
||||||
|
|
||||||
|
// First corner
|
||||||
|
vec3 i = floor(v + dot(v, C.yyy));
|
||||||
|
vec3 x0 = v - i + dot(i, C.xxx);
|
||||||
|
|
||||||
|
// Other corners
|
||||||
|
vec3 g = step(x0.yzx, x0.xyz);
|
||||||
|
vec3 l = 1.0 - g;
|
||||||
|
vec3 i1 = min(g.xyz, l.zxy);
|
||||||
|
vec3 i2 = max(g.xyz, l.zxy);
|
||||||
|
|
||||||
|
vec3 x1 = x0 - i1 + C.xxx;
|
||||||
|
vec3 x2 = x0 - i2 + C.yyy; // 2.0*C.x = 1/3 = C.y
|
||||||
|
vec3 x3 = x0 - D.yyy; // -1.0+3.0*C.x = -0.5 = -D.y
|
||||||
|
|
||||||
|
// Permutations
|
||||||
|
i = mod289(i);
|
||||||
|
vec4 p = permute(
|
||||||
|
permute(
|
||||||
|
permute(i.z + vec4(0.0, i1.z, i2.z, 1.0)) + i.y
|
||||||
|
+ vec4(0.0, i1.y, i2.y, 1.0)) + i.x
|
||||||
|
+ vec4(0.0, i1.x, i2.x, 1.0));
|
||||||
|
|
||||||
|
// Gradients: 7x7 points over a square, mapped onto an octahedron.
|
||||||
|
// The ring size 17*17 = 289 is close to a multiple of 49 (49*6 = 294)
|
||||||
|
float n_ = 0.142857142857; // 1.0/7.0
|
||||||
|
vec3 ns = n_ * D.wyz - D.xzx;
|
||||||
|
|
||||||
|
vec4 j = p - 49.0 * floor(p * ns.z * ns.z); // mod(p,7*7)
|
||||||
|
|
||||||
|
vec4 x_ = floor(j * ns.z);
|
||||||
|
vec4 y_ = floor(j - 7.0 * x_); // mod(j,N)
|
||||||
|
|
||||||
|
vec4 x = x_ * ns.x + ns.yyyy;
|
||||||
|
vec4 y = y_ * ns.x + ns.yyyy;
|
||||||
|
vec4 h = 1.0 - abs(x) - abs(y);
|
||||||
|
|
||||||
|
vec4 b0 = vec4(x.xy, y.xy);
|
||||||
|
vec4 b1 = vec4(x.zw, y.zw);
|
||||||
|
|
||||||
|
//vec4 s0 = vec4(lessThan(b0,0.0))*2.0 - 1.0;
|
||||||
|
//vec4 s1 = vec4(lessThan(b1,0.0))*2.0 - 1.0;
|
||||||
|
vec4 s0 = floor(b0) * 2.0 + 1.0;
|
||||||
|
vec4 s1 = floor(b1) * 2.0 + 1.0;
|
||||||
|
vec4 sh = -step(h, vec4(0.0));
|
||||||
|
|
||||||
|
vec4 a0 = b0.xzyw + s0.xzyw * sh.xxyy;
|
||||||
|
vec4 a1 = b1.xzyw + s1.xzyw * sh.zzww;
|
||||||
|
|
||||||
|
vec3 p0 = vec3(a0.xy, h.x);
|
||||||
|
vec3 p1 = vec3(a0.zw, h.y);
|
||||||
|
vec3 p2 = vec3(a1.xy, h.z);
|
||||||
|
vec3 p3 = vec3(a1.zw, h.w);
|
||||||
|
|
||||||
|
//Normalise gradients
|
||||||
|
vec4 norm = taylorInvSqrt(
|
||||||
|
vec4(dot(p0, p0), dot(p1, p1), dot(p2, p2), dot(p3, p3)));
|
||||||
|
p0 *= norm.x;
|
||||||
|
p1 *= norm.y;
|
||||||
|
p2 *= norm.z;
|
||||||
|
p3 *= norm.w;
|
||||||
|
|
||||||
|
// Mix final noise value
|
||||||
|
vec4 m = max(0.6 - vec4(dot(x0, x0), dot(x1, x1), dot(x2, x2), dot(x3, x3)),
|
||||||
|
0.0);
|
||||||
|
m = m * m;
|
||||||
|
return 42.0
|
||||||
|
* dot(m * m, vec4(dot(p0, x0), dot(p1, x1), dot(p2, x2), dot(p3, x3)));
|
||||||
|
}
|
||||||
|
|
||||||
|
float snoise(vec2 v) {
|
||||||
|
const vec4 C = vec4(0.211324865405187, // (3.0-sqrt(3.0))/6.0
|
||||||
|
0.366025403784439, // 0.5*(sqrt(3.0)-1.0)
|
||||||
|
-0.577350269189626, // -1.0 + 2.0 * C.x
|
||||||
|
0.024390243902439); // 1.0 / 41.0
|
||||||
|
// First corner
|
||||||
|
vec2 i = floor(v + dot(v, C.yy));
|
||||||
|
vec2 x0 = v - i + dot(i, C.xx);
|
||||||
|
|
||||||
|
// Other corners
|
||||||
|
vec2 i1;
|
||||||
|
i1 = (x0.x > x0.y) ? vec2(1.0, 0.0) : vec2(0.0, 1.0);
|
||||||
|
vec4 x12 = x0.xyxy + C.xxzz;
|
||||||
|
x12.xy -= i1;
|
||||||
|
|
||||||
|
// Permutations
|
||||||
|
i = mod289(i); // Avoid truncation effects in permutation
|
||||||
|
vec3 p = permute(
|
||||||
|
permute(i.y + vec3(0.0, i1.y, 1.0)) + i.x + vec3(0.0, i1.x, 1.0));
|
||||||
|
|
||||||
|
vec3 m = max(0.5 - vec3(dot(x0, x0), dot(x12.xy, x12.xy), dot(x12.zw, x12.zw)),
|
||||||
|
0.0);
|
||||||
|
m = m * m;
|
||||||
|
m = m * m;
|
||||||
|
|
||||||
|
// Gradients: 41 points uniformly over a line, mapped onto a diamond.
|
||||||
|
// The ring size 17*17 = 289 is close to a multiple of 41 (41*7 = 287)
|
||||||
|
|
||||||
|
vec3 x = 2.0 * fract(p * C.www) - 1.0;
|
||||||
|
vec3 h = abs(x) - 0.5;
|
||||||
|
vec3 ox = floor(x + 0.5);
|
||||||
|
vec3 a0 = x - ox;
|
||||||
|
|
||||||
|
// Normalise gradients implicitly by scaling m
|
||||||
|
// Approximation of: m *= inversesqrt( a0*a0 + h*h );
|
||||||
|
m *= 1.79284291400159 - 0.85373472095314 * (a0 * a0 + h * h);
|
||||||
|
|
||||||
|
// Compute final noise value at P
|
||||||
|
vec3 g;
|
||||||
|
g.x = a0.x * x0.x + h.x * x0.y;
|
||||||
|
g.yz = a0.yz * x12.xz + h.yz * x12.yw;
|
||||||
|
return 130.0 * dot(m, g);
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO add more uniforms
|
||||||
|
uniform float iGlobalTime; // shader playback time (in seconds)
|
||||||
|
uniform vec3 iWorldScale; // the dimensions of the object being rendered
|
||||||
|
|
||||||
|
// TODO add support for textures
|
||||||
|
// TODO document available inputs other than the uniforms
|
||||||
|
// TODO provide world scale in addition to the untransformed position
|
||||||
|
|
||||||
|
#define PROCEDURAL 1
|
||||||
|
|
||||||
|
//PROCEDURAL_VERSION
|
||||||
|
)SHADER";
|
|
@ -40,4 +40,4 @@ add_dependency_external_projects(oglplus)
|
||||||
find_package(OGLPLUS REQUIRED)
|
find_package(OGLPLUS REQUIRED)
|
||||||
target_include_directories(${TARGET_NAME} PUBLIC ${OGLPLUS_INCLUDE_DIRS})
|
target_include_directories(${TARGET_NAME} PUBLIC ${OGLPLUS_INCLUDE_DIRS})
|
||||||
|
|
||||||
link_hifi_libraries(animation fbx shared gpu model render environment)
|
link_hifi_libraries(shared gpu gpu-networking procedural model render environment animation fbx)
|
||||||
|
|
|
@ -1,171 +1,2 @@
|
||||||
//
|
// Compatibility
|
||||||
// TextureCache.h
|
#include <gpu-networking/TextureCache.h>
|
||||||
// interface/src/renderer
|
|
||||||
//
|
|
||||||
// Created by Andrzej Kapolka on 8/6/13.
|
|
||||||
// Copyright 2013 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
|
|
||||||
//
|
|
||||||
|
|
||||||
#ifndef hifi_TextureCache_h
|
|
||||||
#define hifi_TextureCache_h
|
|
||||||
|
|
||||||
#include <gpu/Texture.h>
|
|
||||||
#include <model/Light.h>
|
|
||||||
|
|
||||||
#include <QImage>
|
|
||||||
#include <QMap>
|
|
||||||
#include <QColor>
|
|
||||||
|
|
||||||
#include <DependencyManager.h>
|
|
||||||
#include <ResourceCache.h>
|
|
||||||
|
|
||||||
namespace gpu {
|
|
||||||
class Batch;
|
|
||||||
}
|
|
||||||
class NetworkTexture;
|
|
||||||
|
|
||||||
typedef QSharedPointer<NetworkTexture> NetworkTexturePointer;
|
|
||||||
|
|
||||||
enum TextureType { DEFAULT_TEXTURE, NORMAL_TEXTURE, SPECULAR_TEXTURE, EMISSIVE_TEXTURE, SPLAT_TEXTURE, CUBE_TEXTURE };
|
|
||||||
|
|
||||||
/// Stores cached textures, including render-to-texture targets.
|
|
||||||
class TextureCache : public ResourceCache, public Dependency {
|
|
||||||
Q_OBJECT
|
|
||||||
SINGLETON_DEPENDENCY
|
|
||||||
|
|
||||||
public:
|
|
||||||
/// Returns the ID of the permutation/normal texture used for Perlin noise shader programs. This texture
|
|
||||||
/// has two lines: the first, a set of random numbers in [0, 255] to be used as permutation offsets, and
|
|
||||||
/// the second, a set of random unit vectors to be used as noise gradients.
|
|
||||||
const gpu::TexturePointer& getPermutationNormalTexture();
|
|
||||||
|
|
||||||
/// Returns an opaque white texture (useful for a default).
|
|
||||||
const gpu::TexturePointer& getWhiteTexture();
|
|
||||||
|
|
||||||
/// Returns an opaque gray texture (useful for a default).
|
|
||||||
const gpu::TexturePointer& getGrayTexture();
|
|
||||||
|
|
||||||
/// Returns the a pale blue texture (useful for a normal map).
|
|
||||||
const gpu::TexturePointer& getBlueTexture();
|
|
||||||
|
|
||||||
/// Returns the a black texture (useful for a default).
|
|
||||||
const gpu::TexturePointer& getBlackTexture();
|
|
||||||
|
|
||||||
// Returns a map used to compress the normals through a fitting scale algorithm
|
|
||||||
const gpu::TexturePointer& getNormalFittingTexture();
|
|
||||||
|
|
||||||
/// Returns a texture version of an image file
|
|
||||||
static gpu::TexturePointer getImageTexture(const QString& path);
|
|
||||||
|
|
||||||
/// Loads a texture from the specified URL.
|
|
||||||
NetworkTexturePointer getTexture(const QUrl& url, TextureType type = DEFAULT_TEXTURE, bool dilatable = false,
|
|
||||||
const QByteArray& content = QByteArray());
|
|
||||||
|
|
||||||
protected:
|
|
||||||
|
|
||||||
virtual QSharedPointer<Resource> createResource(const QUrl& url,
|
|
||||||
const QSharedPointer<Resource>& fallback, bool delayLoad, const void* extra);
|
|
||||||
|
|
||||||
private:
|
|
||||||
TextureCache();
|
|
||||||
virtual ~TextureCache();
|
|
||||||
friend class DilatableNetworkTexture;
|
|
||||||
|
|
||||||
gpu::TexturePointer _permutationNormalTexture;
|
|
||||||
gpu::TexturePointer _whiteTexture;
|
|
||||||
gpu::TexturePointer _grayTexture;
|
|
||||||
gpu::TexturePointer _blueTexture;
|
|
||||||
gpu::TexturePointer _blackTexture;
|
|
||||||
gpu::TexturePointer _normalFittingTexture;
|
|
||||||
|
|
||||||
QHash<QUrl, QWeakPointer<NetworkTexture> > _dilatableNetworkTextures;
|
|
||||||
};
|
|
||||||
|
|
||||||
/// A simple object wrapper for an OpenGL texture.
|
|
||||||
class Texture {
|
|
||||||
public:
|
|
||||||
friend class TextureCache;
|
|
||||||
friend class DilatableNetworkTexture;
|
|
||||||
Texture();
|
|
||||||
~Texture();
|
|
||||||
|
|
||||||
const gpu::TexturePointer& getGPUTexture() const { return _gpuTexture; }
|
|
||||||
|
|
||||||
protected:
|
|
||||||
gpu::TexturePointer _gpuTexture;
|
|
||||||
|
|
||||||
private:
|
|
||||||
};
|
|
||||||
|
|
||||||
/// A texture loaded from the network.
|
|
||||||
|
|
||||||
class NetworkTexture : public Resource, public Texture {
|
|
||||||
Q_OBJECT
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
NetworkTexture(const QUrl& url, TextureType type, const QByteArray& content);
|
|
||||||
|
|
||||||
/// Checks whether it "looks like" this texture is translucent
|
|
||||||
/// (majority of pixels neither fully opaque or fully transparent).
|
|
||||||
bool isTranslucent() const { return _translucent; }
|
|
||||||
|
|
||||||
/// Returns the lazily-computed average texture color.
|
|
||||||
const QColor& getAverageColor() const { return _averageColor; }
|
|
||||||
|
|
||||||
int getOriginalWidth() const { return _originalWidth; }
|
|
||||||
int getOriginalHeight() const { return _originalHeight; }
|
|
||||||
int getWidth() const { return _width; }
|
|
||||||
int getHeight() const { return _height; }
|
|
||||||
TextureType getType() const { return _type; }
|
|
||||||
protected:
|
|
||||||
|
|
||||||
virtual void downloadFinished(const QByteArray& data) override;
|
|
||||||
|
|
||||||
Q_INVOKABLE void loadContent(const QByteArray& content);
|
|
||||||
// FIXME: This void* should be a gpu::Texture* but i cannot get it to work for now, moving on...
|
|
||||||
Q_INVOKABLE void setImage(const QImage& image, void* texture, bool translucent, const QColor& averageColor, int originalWidth,
|
|
||||||
int originalHeight);
|
|
||||||
|
|
||||||
virtual void imageLoaded(const QImage& image);
|
|
||||||
|
|
||||||
TextureType _type;
|
|
||||||
|
|
||||||
private:
|
|
||||||
bool _translucent;
|
|
||||||
QColor _averageColor;
|
|
||||||
int _originalWidth;
|
|
||||||
int _originalHeight;
|
|
||||||
int _width;
|
|
||||||
int _height;
|
|
||||||
};
|
|
||||||
|
|
||||||
/// Caches derived, dilated textures.
|
|
||||||
class DilatableNetworkTexture : public NetworkTexture {
|
|
||||||
Q_OBJECT
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
DilatableNetworkTexture(const QUrl& url, const QByteArray& content);
|
|
||||||
|
|
||||||
/// Returns a pointer to a texture with the requested amount of dilation.
|
|
||||||
QSharedPointer<Texture> getDilatedTexture(float dilation);
|
|
||||||
|
|
||||||
protected:
|
|
||||||
|
|
||||||
virtual void imageLoaded(const QImage& image);
|
|
||||||
virtual void reinsert();
|
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
QImage _image;
|
|
||||||
int _innerRadius;
|
|
||||||
int _outerRadius;
|
|
||||||
|
|
||||||
QMap<float, QWeakPointer<Texture> > _dilatedTextures;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // hifi_TextureCache_h
|
|
||||||
|
|
|
@ -18,12 +18,39 @@
|
||||||
// the interpolated normal
|
// the interpolated normal
|
||||||
in vec3 _normal;
|
in vec3 _normal;
|
||||||
in vec3 _color;
|
in vec3 _color;
|
||||||
|
in vec2 _texCoord0;
|
||||||
|
in vec4 _position;
|
||||||
|
|
||||||
|
//PROCEDURAL_COMMON_BLOCK
|
||||||
|
|
||||||
|
#line 1001
|
||||||
|
//PROCEDURAL_BLOCK
|
||||||
|
|
||||||
|
#line 2030
|
||||||
void main(void) {
|
void main(void) {
|
||||||
Material material = getMaterial();
|
Material material = getMaterial();
|
||||||
packDeferredFragment(
|
vec3 normal = normalize(_normal.xyz);
|
||||||
normalize(_normal.xyz),
|
vec3 diffuse = _color.rgb;
|
||||||
glowIntensity,
|
vec3 specular = DEFAULT_SPECULAR;
|
||||||
_color.rgb,
|
float shininess = DEFAULT_SHININESS;
|
||||||
DEFAULT_SPECULAR, DEFAULT_SHININESS);
|
float emissiveAmount = 0.0;
|
||||||
|
|
||||||
|
#ifdef PROCEDURAL
|
||||||
|
|
||||||
|
#ifdef PROCEDURAL_V1
|
||||||
|
specular = getProceduralColor().rgb;
|
||||||
|
emissiveAmount = 1.0;
|
||||||
|
#else
|
||||||
|
emissiveAmount = getProceduralColors(diffuse, specular, shininess);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (emissiveAmount > 0.0) {
|
||||||
|
packDeferredFragmentLightmap(
|
||||||
|
normal, glowIntensity, diffuse, specular, shininess, specular);
|
||||||
|
} else {
|
||||||
|
packDeferredFragment(
|
||||||
|
normal, glowIntensity, diffuse, specular, shininess);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,4 +7,4 @@ add_dependency_external_projects(glm)
|
||||||
find_package(GLM REQUIRED)
|
find_package(GLM REQUIRED)
|
||||||
target_include_directories(${TARGET_NAME} PUBLIC ${GLM_INCLUDE_DIRS})
|
target_include_directories(${TARGET_NAME} PUBLIC ${GLM_INCLUDE_DIRS})
|
||||||
|
|
||||||
link_hifi_libraries(shared octree gpu model fbx entities animation audio physics)
|
link_hifi_libraries(shared networking octree gpu gpu-networking procedural model fbx entities animation audio physics)
|
||||||
|
|
|
@ -10,6 +10,6 @@ set_target_properties(${TARGET_NAME} PROPERTIES FOLDER "Tests/manual-tests/")
|
||||||
#include_oglplus()
|
#include_oglplus()
|
||||||
|
|
||||||
# link in the shared libraries
|
# link in the shared libraries
|
||||||
link_hifi_libraries(render-utils gpu shared networking fbx model animation script-engine)
|
link_hifi_libraries(networking gpu gpu-networking procedural shared fbx model animation script-engine render-utils )
|
||||||
|
|
||||||
copy_dlls_beside_windows_executable()
|
copy_dlls_beside_windows_executable()
|
Loading…
Reference in a new issue