Osd drawing API refactoring.

Remove DrawRegistry from osd layer and put a simple shader caching
utility into examples/common. osd layer only provides patch shader
snippet and let client configure and compile the code. Clients also
maintain the lifetime of shader object, which is preferable for the
actual application integration.

update all examples to use the new scheme.
This commit is contained in:
Takahito Tejima 2015-05-13 17:35:46 -07:00
parent a0e3b59ae5
commit 4a4322983f
30 changed files with 3097 additions and 3635 deletions

View File

@ -43,6 +43,7 @@ set(EXAMPLES_COMMON_HEADER_FILES
hud.h
objAnim.h
patchColors.h
shaderCache.h
simple_math.h
stb_image_write.h
stopwatch.h
@ -51,15 +52,18 @@ set(EXAMPLES_COMMON_HEADER_FILES
if( OPENGL_FOUND AND (GLEW_FOUND AND GLFW_FOUND) OR (APPLE AND GLFW_FOUND))
list(APPEND EXAMPLES_COMMON_SOURCE_FILES
# we will rename gl_xxx to glXxx
gl_common.cpp
gl_framebuffer.cpp
gl_hud.cpp
glShaderCache.cpp
)
list(APPEND EXAMPLES_COMMON_HEADER_FILES
gl_common.h
gl_framebuffer.h
gl_hud.h
glShaderCache.h
)
if (NOT "${OPENGL_INCLUDE_DIR}" STREQUAL "")
@ -77,10 +81,12 @@ if(DXSDK_FOUND)
list(APPEND EXAMPLES_COMMON_SOURCE_FILES
d3d11_hud.cpp
d3d11ShaderCache.cpp
)
list(APPEND EXAMPLES_COMMON_HEADER_FILES
d3d11_hud.h
d3d11ShaderCache.h
)
include_directories("${DXSDK_INCLUDE_DIR}")

View File

@ -0,0 +1,186 @@
//
// Copyright 2015 Pixar
//
// Licensed under the Apache License, Version 2.0 (the "Apache License")
// with the following modification; you may not use this file except in
// compliance with the Apache License and the following modification to it:
// Section 6. Trademarks. is deleted and replaced with:
//
// 6. Trademarks. This License does not grant permission to use the trade
// names, trademarks, service marks, or product names of the Licensor
// and its affiliates, except as required to comply with Section 4(c) of
// the License and to reproduce the content of the NOTICE file.
//
// You may obtain a copy of the Apache License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the Apache License with the above modification is
// distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the Apache License for the specific
// language governing permissions and limitations under the Apache License.
//
#include "d3d11ShaderCache.h"
#include <D3D11.h>
#include <D3Dcompiler.h>
#include <far/error.h>
D3D11DrawConfig::D3D11DrawConfig()
: _vertexShader(NULL), _hullShader(NULL), _domainShader(NULL),
_geometryShader(NULL), _pixelShader(NULL) {
}
D3D11DrawConfig::~D3D11DrawConfig() {
if (_vertexShader) _vertexShader->Release();
if (_hullShader) _hullShader->Release();
if (_domainShader) _domainShader->Release();
if (_geometryShader) _geometryShader->Release();
if (_pixelShader) _pixelShader->Release();
}
static ID3DBlob *
_CompileShader(std::string const &target,
std::string const &entry,
std::string const &shaderSource) {
DWORD dwShaderFlags = D3DCOMPILE_ENABLE_STRICTNESS;
#ifdef _DEBUG
dwShaderFlags |= D3DCOMPILE_DEBUG;
#endif
ID3DBlob* pBlob = NULL;
ID3DBlob* pBlobError = NULL;
HRESULT hr = D3DCompile(shaderSource.c_str(), shaderSource.size(),
NULL, NULL, NULL,
entry.c_str(), target.c_str(),
dwShaderFlags, 0, &pBlob, &pBlobError);
if (FAILED(hr)) {
if ( pBlobError != NULL ) {
OpenSubdiv::Far::Error(OpenSubdiv::Far::FAR_RUNTIME_ERROR,
"Error compiling HLSL shader: %s\n",
(CHAR*)pBlobError->GetBufferPointer());
pBlobError->Release();
return NULL;
}
}
return pBlob;
}
bool
D3D11DrawConfig::CompileVertexShader(const std::string &target,
const std::string &entry,
const std::string &source,
ID3D11InputLayout ** ppInputLayout,
D3D11_INPUT_ELEMENT_DESC const * pInputElementDescs,
int numInputElements,
ID3D11Device * pd3dDevice) {
ID3DBlob * pBlob = NULL;
pBlob = _CompileShader(target, entry, source);
HRESULT hr = pd3dDevice->CreateVertexShader(pBlob->GetBufferPointer(),
pBlob->GetBufferSize(),
NULL,
&_vertexShader);
if (FAILED(hr)) {
return false;
}
if (ppInputLayout and !*ppInputLayout) {
hr = pd3dDevice->CreateInputLayout(
pInputElementDescs, numInputElements,
pBlob->GetBufferPointer(),
pBlob->GetBufferSize(), ppInputLayout);
if (FAILED(hr)) {
return false;
}
}
if (pBlob) pBlob->Release();
return true;
}
bool
D3D11DrawConfig::CompileHullShader(const std::string &target,
const std::string &entry,
const std::string &source,
ID3D11Device * pd3dDevice) {
ID3DBlob * pBlob = NULL;
pBlob = _CompileShader(target, entry, source);
HRESULT hr = pd3dDevice->CreateHullShader(pBlob->GetBufferPointer(),
pBlob->GetBufferSize(),
NULL,
&_hullShader);
if (FAILED(hr)) {
return false;
}
if (pBlob) pBlob->Release();
return true;
}
bool
D3D11DrawConfig::CompileDomainShader(const std::string &target,
const std::string &entry,
const std::string &source,
ID3D11Device * pd3dDevice) {
ID3DBlob * pBlob = NULL;
pBlob = _CompileShader(target, entry, source);
HRESULT hr = pd3dDevice->CreateDomainShader(pBlob->GetBufferPointer(),
pBlob->GetBufferSize(),
NULL,
&_domainShader);
if (FAILED(hr)) {
return false;
}
if (pBlob) pBlob->Release();
return true;
}
bool
D3D11DrawConfig::CompileGeometryShader(const std::string &target,
const std::string &entry,
const std::string &source,
ID3D11Device * pd3dDevice) {
ID3DBlob * pBlob = NULL;
pBlob = _CompileShader(target, entry, source);
HRESULT hr = pd3dDevice->CreateGeometryShader(pBlob->GetBufferPointer(),
pBlob->GetBufferSize(),
NULL,
&_geometryShader);
if (FAILED(hr)) {
return false;
}
if (pBlob) pBlob->Release();
return true;
}
bool
D3D11DrawConfig::CompilePixelShader(const std::string &target,
const std::string &entry,
const std::string &source,
ID3D11Device * pd3dDevice) {
ID3DBlob * pBlob = NULL;
pBlob = _CompileShader(target, entry, source);
HRESULT hr = pd3dDevice->CreatePixelShader(pBlob->GetBufferPointer(),
pBlob->GetBufferSize(),
NULL,
&_pixelShader);
if (FAILED(hr)) {
return false;
}
if (pBlob) pBlob->Release();
return true;
}

View File

@ -0,0 +1,93 @@
//
// Copyright 2015 Pixar
//
// Licensed under the Apache License, Version 2.0 (the "Apache License")
// with the following modification; you may not use this file except in
// compliance with the Apache License and the following modification to it:
// Section 6. Trademarks. is deleted and replaced with:
//
// 6. Trademarks. This License does not grant permission to use the trade
// names, trademarks, service marks, or product names of the Licensor
// and its affiliates, except as required to comply with Section 4(c) of
// the License and to reproduce the content of the NOTICE file.
//
// You may obtain a copy of the Apache License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the Apache License with the above modification is
// distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the Apache License for the specific
// language governing permissions and limitations under the Apache License.
//
#ifndef OPENSUBDIV_EXAMPLES_D3D11_SHADER_CACHE_H
#define OPENSUBDIV_EXAMPLES_D3D11_SHADER_CACHE_H
#include <string>
#include "./shaderCache.h"
struct ID3D11VertexShader;
struct ID3D11HullShader;
struct ID3D11DomainShader;
struct ID3D11GeometryShader;
struct ID3D11PixelShader;
struct ID3D11Device;
struct ID3D11InputLayout;
struct D3D11_INPUT_ELEMENT_DESC;
class D3D11DrawConfig {
public:
D3D11DrawConfig();
~D3D11DrawConfig();
bool CompileVertexShader(const std::string &target,
const std::string &entry,
const std::string &source,
ID3D11InputLayout ** ppInputLayout,
D3D11_INPUT_ELEMENT_DESC const *pInputElementDescs,
int numInputElements,
ID3D11Device * pd3dDevice);
bool CompileHullShader(const std::string &target,
const std::string &entry,
const std::string &source,
ID3D11Device * pd3dDevice);
bool CompileDomainShader(const std::string &target,
const std::string &entry,
const std::string &source,
ID3D11Device * pd3dDevice);
bool CompileGeometryShader(const std::string &target,
const std::string &entry,
const std::string &source,
ID3D11Device * pd3dDevice);
bool CompilePixelShader(const std::string &target,
const std::string &entry,
const std::string &source,
ID3D11Device * pd3dDevice);
ID3D11VertexShader *GetVertexShader() const { return _vertexShader; }
ID3D11HullShader *GetHullShader() const { return _hullShader; }
ID3D11DomainShader *GetDomainShader() const { return _domainShader; }
ID3D11GeometryShader *GetGeometryShader() const { return _geometryShader; }
ID3D11PixelShader *GetPixelShader() const { return _pixelShader; }
private:
ID3D11VertexShader *_vertexShader;
ID3D11HullShader *_hullShader;
ID3D11DomainShader *_domainShader;
ID3D11GeometryShader *_geometryShader;
ID3D11PixelShader *_pixelShader;
};
// workaround for template alias
#if 0
template <typename DESC_TYPE>
using D3D11ShaderCache = ShaderCacheT<DESC_TYPE, D3D11DrawConfig>;
#else
template <typename DESC_TYPE>
class D3D11ShaderCache : public ShaderCacheT<DESC_TYPE, D3D11DrawConfig> {
};
#endif
#endif // OPENSUBDIV_EXAMPLES_D3D11_SHADER_CACHE_H

View File

@ -0,0 +1,98 @@
//
// Copyright 2015 Pixar
//
// Licensed under the Apache License, Version 2.0 (the "Apache License")
// with the following modification; you may not use this file except in
// compliance with the Apache License and the following modification to it:
// Section 6. Trademarks. is deleted and replaced with:
//
// 6. Trademarks. This License does not grant permission to use the trade
// names, trademarks, service marks, or product names of the Licensor
// and its affiliates, except as required to comply with Section 4(c) of
// the License and to reproduce the content of the NOTICE file.
//
// You may obtain a copy of the Apache License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the Apache License with the above modification is
// distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the Apache License for the specific
// language governing permissions and limitations under the Apache License.
//
#include "glShaderCache.h"
#include <vector>
#include <osd/opengl.h>
#include <far/error.h>
GLDrawConfig::GLDrawConfig(const std::string &version)
: _version(version), _numShaders(0) {
_program = glCreateProgram();
}
GLDrawConfig::~GLDrawConfig() {
if (_program)
glDeleteProgram(_program);
}
bool
GLDrawConfig::CompileAndAttachShader(GLenum shaderType,
const std::string &source) {
GLuint shader = glCreateShader(shaderType);
const char *sources[2];
sources[0] = _version.c_str();
sources[1] = source.c_str();
glShaderSource(shader, 2, sources, NULL);
glCompileShader(shader);
GLint status;
glGetShaderiv(shader, GL_COMPILE_STATUS, &status);
if (status == GL_FALSE) {
GLint infoLogLength;
glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLogLength);
char * infoLog = new char[infoLogLength];
glGetShaderInfoLog(shader, infoLogLength, NULL, infoLog);
OpenSubdiv::Far::Error(OpenSubdiv::Far::FAR_RUNTIME_ERROR,
"Error compiling GLSL shader: %s\n",
infoLog);
delete[] infoLog;
return false;
}
glAttachShader(_program, shader);
++_numShaders;
return true;
}
bool
GLDrawConfig::Link() {
glLinkProgram(_program);
std::vector<GLuint> shaders(_numShaders);
GLsizei count = 0;
glGetAttachedShaders(_program, _numShaders, &count, &shaders[0]);
for (int i = 0; i < (int)count; ++i) {
glDeleteShader(shaders[i]);
}
GLint status;
glGetProgramiv(_program, GL_LINK_STATUS, &status );
if (status == GL_FALSE) {
GLint infoLogLength;
glGetProgramiv(_program, GL_INFO_LOG_LENGTH, &infoLogLength);
char * infoLog = new char[infoLogLength];
glGetProgramInfoLog(_program, infoLogLength, NULL, infoLog);
OpenSubdiv::Far::Error(OpenSubdiv::Far::FAR_RUNTIME_ERROR,
"Error linking GLSL program: %s\n", infoLog);
delete[] infoLog;
return false;
}
return true;
}

View File

@ -0,0 +1,62 @@
//
// Copyright 2015 Pixar
//
// Licensed under the Apache License, Version 2.0 (the "Apache License")
// with the following modification; you may not use this file except in
// compliance with the Apache License and the following modification to it:
// Section 6. Trademarks. is deleted and replaced with:
//
// 6. Trademarks. This License does not grant permission to use the trade
// names, trademarks, service marks, or product names of the Licensor
// and its affiliates, except as required to comply with Section 4(c) of
// the License and to reproduce the content of the NOTICE file.
//
// You may obtain a copy of the Apache License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the Apache License with the above modification is
// distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the Apache License for the specific
// language governing permissions and limitations under the Apache License.
//
#ifndef OPENSUBDIV_EXAMPLES_GL_SHADER_CACHE_H
#define OPENSUBDIV_EXAMPLES_GL_SHADER_CACHE_H
#include <osd/opengl.h>
#include <map>
#include <string>
#include "./shaderCache.h"
class GLDrawConfig {
public:
explicit GLDrawConfig(const std::string &version);
~GLDrawConfig();
bool CompileAndAttachShader(GLenum shaderType, const std::string &source);
bool Link();
GLuint GetProgram() const {
return _program;
}
private:
GLuint _program;
std::string _version;
int _numShaders;
};
// workaround for template alias
#if 0
template <typename DESC_TYPE>
using GLShaderCache = ShaderCacheT<DESC_TYPE, GLDrawConfig>;
#else
template <typename DESC_TYPE>
class GLShaderCache : public ShaderCacheT<DESC_TYPE, GLDrawConfig> {
};
#endif
#endif // OPENSUBDIV_EXAMPLES_GL_SHADER_CACHE_H

View File

@ -0,0 +1,70 @@
//
// Copyright 2015 Pixar
//
// Licensed under the Apache License, Version 2.0 (the "Apache License")
// with the following modification; you may not use this file except in
// compliance with the Apache License and the following modification to it:
// Section 6. Trademarks. is deleted and replaced with:
//
// 6. Trademarks. This License does not grant permission to use the trade
// names, trademarks, service marks, or product names of the Licensor
// and its affiliates, except as required to comply with Section 4(c) of
// the License and to reproduce the content of the NOTICE file.
//
// You may obtain a copy of the Apache License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the Apache License with the above modification is
// distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the Apache License for the specific
// language governing permissions and limitations under the Apache License.
//
#ifndef OPENSUBDIV_EXAMPLES_SHADER_CACHE_H
#define OPENSUBDIV_EXAMPLES_SHADER_CACHE_H
#include <map>
template <typename DESC_TYPE, typename CONFIG_TYPE>
class ShaderCacheT {
public:
typedef DESC_TYPE DescType;
typedef CONFIG_TYPE ConfigType;
typedef std::map<DescType, ConfigType *> ConfigMap;
virtual ~ShaderCacheT() {
Reset();
}
void Reset() {
for (typename ConfigMap::iterator it = _configMap.begin();
it != _configMap.end(); ++it) {
delete it->second;
}
_configMap.clear();
}
// fetch shader config
ConfigType * GetDrawConfig(DescType const & desc) {
typename ConfigMap::iterator it = _configMap.find(desc);
if (it != _configMap.end()) {
return it->second;
} else {
ConfigType * config = CreateDrawConfig(desc);
if (config) {
_configMap[desc] = config;
}
return config;
}
}
virtual ConfigType *CreateDrawConfig(DescType const &desc) = 0;
private:
ConfigMap _configMap;
};
#endif // OPENSUBDIV_EXAMPLES_SHADER_CACHE_H

View File

@ -26,7 +26,6 @@
#include <D3Dcompiler.h>
#include <osd/d3d11DrawContext.h>
#include <osd/d3d11DrawRegistry.h>
#include <far/error.h>
#include <osd/cpuD3D11VertexBuffer.h>
@ -64,7 +63,9 @@ OpenSubdiv::Osd::D3D11MeshInterface *g_mesh;
#include "../common/simple_math.h"
#include "../common/d3d11_hud.h"
#include "../common/d3d11PtexMipmapTexture.h"
#include "../common/d3d11ShaderCache.h"
#include <osd/hlslPatchShaderSource.h>
static const char *g_shaderSource =
#include "shader.gen.h"
;
@ -430,187 +431,212 @@ struct EffectDesc {
}
};
class EffectDrawRegistry : public OpenSubdiv::Osd::D3D11DrawRegistry<EffectDesc> {
class ShaderCache : public D3D11ShaderCache<EffectDesc> {
public:
virtual D3D11DrawConfig *CreateDrawConfig(EffectDesc const &effectDesc) {
using namespace OpenSubdiv;
protected:
virtual ConfigType *
_CreateDrawConfig(EffectDesc const & desc,
SourceConfigType const * sconfig,
ID3D11Device * pd3dDevice,
ID3D11InputLayout ** ppInputLayout,
D3D11_INPUT_ELEMENT_DESC const * pInputElementDescs,
int numInputElements);
D3D11DrawConfig *config = new D3D11DrawConfig();
virtual SourceConfigType *
_CreateDrawSourceConfig(EffectDesc const & desc, ID3D11Device * pd3dDevice);
};
Far::PatchDescriptor::Type type = effectDesc.desc.GetType();
EffectDrawRegistry::SourceConfigType *
EffectDrawRegistry::_CreateDrawSourceConfig(EffectDesc const &effectDesc, ID3D11Device *pd3dDevice)
{
Effect effect = effectDesc.effect;
// common defines
std::stringstream ss;
SourceConfigType * sconfig =
BaseRegistry::_CreateDrawSourceConfig(effectDesc.desc, pd3dDevice);
assert(sconfig);
if (type == Far::PatchDescriptor::QUADS) {
ss << "#define PRIM_QUAD\n";
} else {
ss << "#define PRIM_TRI\n";
}
// legacy gregory patch requires OSD_MAX_VALENCE and OSD_NUM_ELEMENTS defined
if (effectDesc.desc.GetType() == OpenSubdiv::Far::PatchDescriptor::GREGORY or
effectDesc.desc.GetType() == OpenSubdiv::Far::PatchDescriptor::GREGORY_BOUNDARY) {
std::ostringstream ss;
ss << effectDesc.maxValence;
sconfig->commonShader.AddDefine("OSD_MAX_VALENCE", ss.str());
// OSD tessellation controls
if (effectDesc.effect.screenSpaceTess) {
ss << "#define OSD_ENABLE_SCREENSPACE_TESSELLATION\n";
}
if (effectDesc.effect.fractionalSpacing) {
ss << "#define OSD_FRACTIONAL_ODD_SPACING\n";
}
if (effectDesc.effect.patchCull) {
ss << "#define OSD_ENABLE_PATCH_CULL\n";
}
// for legacy gregory
ss << "#define OSD_MAX_VALENCE " << effectDesc.maxValence << "\n";
ss << "#define OSD_NUM_ELEMENTS " << effectDesc.numElements << "\n";
// add ptex functions
ss << D3D11PtexMipmapTexture::GetShaderSource();
// -------------------------------------------------------------
// display styles
// -------------------------------------------------------------
// mipmap
if (effectDesc.effect.seamless) {
ss << "#define SEAMLESS_MIPMAP\n";
}
// wire
if (effectDesc.effect.wire == 0) {
ss << "#define GEOMETRY_OUT_WIRE\n";
} else if (effectDesc.effect.wire == 1) {
ss << "#define GEOMETRY_OUT_FILL\n";
} else if (effectDesc.effect.wire == 2) {
ss << "#define GEOMETRY_OUT_LINE\n";
}
// color
switch(effectDesc.effect.color) {
case COLOR_NONE:
break;
case COLOR_PTEX_NEAREST:
ss << "#define COLOR_PTEX_NEAREST\n";
break;
case COLOR_PTEX_HW_BILINEAR:
ss << "#define COLOR_PTEX_HW_BILINEAR\n";
break;
case COLOR_PTEX_BILINEAR:
ss << "#define COLOR_PTEX_BILINEAR\n";
break;
case COLOR_PTEX_BIQUADRATIC:
ss << "#define COLOR_PTEX_BIQUADRATIC\n";
break;
case COLOR_PATCHTYPE:
ss << "#define COLOR_PATCHTYPE\n";
break;
case COLOR_PATCHCOORD:
ss << "#define COLOR_PATCHCOORD\n";
break;
case COLOR_NORMAL:
ss << "#define COLOR_NORMAL\n";
break;
}
// displacement
switch (effectDesc.effect.displacement) {
case DISPLACEMENT_NONE:
break;
case DISPLACEMENT_HW_BILINEAR:
ss << "#define DISPLACEMENT_HW_BILINEAR\n";
break;
case DISPLACEMENT_BILINEAR:
ss << "#define DISPLACEMENT_BILINEAR\n";
break;
case DISPLACEMENT_BIQUADRATIC:
ss << "#define DISPLACEMENT_BIQUADRATIC\n";
break;
}
// normal
switch (effectDesc.effect.normal) {
case NORMAL_FACET:
ss << "#define NORMAL_FACET\n";
break;
case NORMAL_HW_SCREENSPACE:
ss << "#define NORMAL_HW_SCREENSPACE\n";
break;
case NORMAL_SCREENSPACE:
ss << "#define NORMAL_SCREENSPACE\n";
break;
case NORMAL_BIQUADRATIC:
ss << "#define NORMAL_BIQUADRATIC\n";
break;
case NORMAL_BIQUADRATIC_WG:
ss << "#define OSD_COMPUTE_NORMAL_DERIVATIVES\n";
ss << "#define NORMAL_BIQUADRATIC_WG\n";
break;
}
// occlusion
if (effectDesc.effect.occlusion)
ss << "#define USE_PTEX_OCCLUSION\n";
// specular
if (effectDesc.effect.specular)
ss << "#define USE_PTEX_SPECULAR\n";
// IBL
if (effectDesc.effect.ibl)
ss << "#define USE_IBL\n";
// need for patch color-coding : we need these defines in the fragment shader
if (type == Far::PatchDescriptor::GREGORY) {
ss << "#define OSD_PATCH_GREGORY\n";
} else if (type == Far::PatchDescriptor::GREGORY_BOUNDARY) {
ss << "#define OSD_PATCH_GREGORY_BOUNDARY\n";
} else if (type == Far::PatchDescriptor::GREGORY_BASIS) {
ss << "#define OSD_PATCH_GREGORY_BASIS\n";
}
// include osd PatchCommon
ss << Osd::HLSLPatchShaderSource::GetCommonShaderSource();
std::string common = ss.str();
ss.str("");
ss << effectDesc.numElements;
sconfig->commonShader.AddDefine("OSD_NUM_ELEMENTS", ss.str());
}
// input layout
const D3D11_INPUT_ELEMENT_DESC hInElementDesc[] = {
{ "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 },
{ "NORMAL", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 4*3, D3D11_INPUT_PER_VERTEX_DATA, 0 }
};
// add ptex functions
sconfig->commonShader.source += D3D11PtexMipmapTexture::GetShaderSource();
if (effect.patchCull)
sconfig->commonShader.AddDefine("OSD_ENABLE_PATCH_CULL");
if (effect.screenSpaceTess)
sconfig->commonShader.AddDefine("OSD_ENABLE_SCREENSPACE_TESSELLATION");
if (effect.fractionalSpacing)
sconfig->commonShader.AddDefine("OSD_FRACTIONAL_ODD_SPACING");
bool quad = true;
if (effectDesc.desc.GetType() == OpenSubdiv::Far::PatchDescriptor::QUADS ||
effectDesc.desc.GetType() == OpenSubdiv::Far::PatchDescriptor::TRIANGLES) {
sconfig->vertexShader.source = g_shaderSource;
sconfig->vertexShader.target = "vs_5_0";
sconfig->vertexShader.entry = "vs_main";
if (effect.displacement) {
sconfig->geometryShader.AddDefine("FLAT_NORMALS");
// vertex shader
ss << common
<< g_shaderSource
<< Osd::HLSLPatchShaderSource::GetVertexShaderSource(type);
if (effectDesc.desc.IsAdaptive()) {
config->CompileVertexShader("vs_5_0", "vs_main_patches", ss.str(),
&g_pInputLayout,
hInElementDesc,
ARRAYSIZE(hInElementDesc),
g_pd3dDevice);
} else {
config->CompileVertexShader("vs_5_0", "vs_main",
ss.str(),
&g_pInputLayout,
hInElementDesc,
ARRAYSIZE(hInElementDesc),
g_pd3dDevice);
}
} else {
quad = false;
sconfig->vertexShader.source = g_shaderSource + sconfig->vertexShader.source;
sconfig->domainShader.source = g_shaderSource + sconfig->domainShader.source;
sconfig->hullShader.source = g_shaderSource + sconfig->hullShader.source;
if (effect.displacement and (not effect.normal))
sconfig->geometryShader.AddDefine("FLAT_NORMALS");
}
ss.str("");
sconfig->geometryShader.source = g_shaderSource;
sconfig->geometryShader.target = "gs_5_0";
sconfig->geometryShader.entry = "gs_main";
sconfig->pixelShader.source = g_shaderSource;
sconfig->pixelShader.target = "ps_5_0";
sconfig->pixelShader.entry = "ps_main";
if (effectDesc.desc.IsAdaptive()) {
// hull shader
ss << common
<< g_shaderSource
<< Osd::HLSLPatchShaderSource::GetHullShaderSource(type);
config->CompileHullShader("hs_5_0", "hs_main_patches", ss.str(),
g_pd3dDevice);
ss.str("");
switch (effect.color) {
case COLOR_NONE:
break;
case COLOR_PTEX_NEAREST:
sconfig->pixelShader.AddDefine("COLOR_PTEX_NEAREST");
break;
case COLOR_PTEX_HW_BILINEAR:
sconfig->pixelShader.AddDefine("COLOR_PTEX_HW_BILINEAR");
break;
case COLOR_PTEX_BILINEAR:
sconfig->pixelShader.AddDefine("COLOR_PTEX_BILINEAR");
break;
case COLOR_PTEX_BIQUADRATIC:
sconfig->pixelShader.AddDefine("COLOR_PTEX_BIQUADRATIC");
break;
case COLOR_PATCHTYPE:
sconfig->pixelShader.AddDefine("COLOR_PATCHTYPE");
break;
case COLOR_PATCHCOORD:
sconfig->pixelShader.AddDefine("COLOR_PATCHCOORD");
break;
case COLOR_NORMAL:
sconfig->pixelShader.AddDefine("COLOR_NORMAL");
break;
}
// domain shader
ss << common
<< g_shaderSource
<< Osd::HLSLPatchShaderSource::GetDomainShaderSource(type);
config->CompileDomainShader("ds_5_0", "ds_main_patches", ss.str(),
g_pd3dDevice);
ss.str("");
}
switch (effect.displacement) {
case DISPLACEMENT_NONE:
break;
case DISPLACEMENT_HW_BILINEAR:
sconfig->commonShader.AddDefine("DISPLACEMENT_HW_BILINEAR");
break;
case DISPLACEMENT_BILINEAR:
sconfig->commonShader.AddDefine("DISPLACEMENT_BILINEAR");
break;
case DISPLACEMENT_BIQUADRATIC:
sconfig->commonShader.AddDefine("DISPLACEMENT_BIQUADRATIC");
break;
}
// geometry shader
ss << common
<< g_shaderSource;
config->CompileGeometryShader("gs_5_0", "gs_main", ss.str(),
g_pd3dDevice);
ss.str("");
switch (effect.normal) {
case NORMAL_FACET:
sconfig->commonShader.AddDefine("NORMAL_FACET");
break;
case NORMAL_HW_SCREENSPACE:
sconfig->commonShader.AddDefine("NORMAL_HW_SCREENSPACE");
break;
case NORMAL_SCREENSPACE:
sconfig->commonShader.AddDefine("NORMAL_SCREENSPACE");
break;
case NORMAL_BIQUADRATIC:
sconfig->commonShader.AddDefine("NORMAL_BIQUADRATIC");
break;
case NORMAL_BIQUADRATIC_WG:
sconfig->commonShader.AddDefine("OSD_COMPUTE_NORMAL_DERIVATIVES");
sconfig->commonShader.AddDefine("NORMAL_BIQUADRATIC_WG");
break;
}
// pixel shader
ss << common
<< g_shaderSource;
config->CompilePixelShader("ps_5_0", "ps_main", ss.str(),
g_pd3dDevice);
ss.str("");
if (effect.occlusion)
sconfig->pixelShader.AddDefine("USE_PTEX_OCCLUSION");
if (effect.specular)
sconfig->pixelShader.AddDefine("USE_PTEX_SPECULAR");
if (effect.ibl)
sconfig->pixelShader.AddDefine("USE_IBL");
return config;
};
};
if (quad) {
sconfig->geometryShader.AddDefine("PRIM_QUAD");
sconfig->pixelShader.AddDefine("PRIM_QUAD");
} else {
sconfig->geometryShader.AddDefine("PRIM_TRI");
sconfig->pixelShader.AddDefine("PRIM_TRI");
}
if (effect.seamless) {
sconfig->commonShader.AddDefine("SEAMLESS_MIPMAP");
}
if (effect.wire == 0) {
sconfig->geometryShader.AddDefine("GEOMETRY_OUT_WIRE");
sconfig->pixelShader.AddDefine("GEOMETRY_OUT_WIRE");
} else if (effect.wire == 1) {
sconfig->geometryShader.AddDefine("GEOMETRY_OUT_FILL");
sconfig->pixelShader.AddDefine("GEOMETRY_OUT_FILL");
} else if (effect.wire == 2) {
sconfig->geometryShader.AddDefine("GEOMETRY_OUT_LINE");
sconfig->pixelShader.AddDefine("GEOMETRY_OUT_LINE");
}
return sconfig;
}
EffectDrawRegistry::ConfigType *
EffectDrawRegistry::_CreateDrawConfig(
EffectDesc const & effectDesc,
SourceConfigType const * sconfig,
ID3D11Device * pd3dDevice,
ID3D11InputLayout ** ppInputLayout,
D3D11_INPUT_ELEMENT_DESC const * pInputElementDescs,
int numInputElements) {
ConfigType * config = BaseRegistry::_CreateDrawConfig(effectDesc.desc, sconfig,
pd3dDevice, ppInputLayout, pInputElementDescs, numInputElements);
assert(config);
return config;
}
EffectDrawRegistry effectRegistry;
ShaderCache g_shaderCache;
//------------------------------------------------------------------------------
D3D11PtexMipmapTexture *
@ -804,16 +830,7 @@ bindProgram(Effect effect, OpenSubdiv::Osd::DrawContext::PatchArray const & patc
effectDesc.numElements = numElements;
}
// input layout
const D3D11_INPUT_ELEMENT_DESC hInElementDesc[] = {
{ "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 },
{ "NORMAL", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 4*3, D3D11_INPUT_PER_VERTEX_DATA, 0 }
};
EffectDrawRegistry::ConfigType *
config = effectRegistry.GetDrawConfig(
effectDesc, g_pd3dDevice,
&g_pInputLayout, hInElementDesc, ARRAYSIZE(hInElementDesc));
D3D11DrawConfig *config = g_shaderCache.GetDrawConfig(effectDesc);
assert(g_pInputLayout);
@ -921,17 +938,17 @@ bindProgram(Effect effect, OpenSubdiv::Osd::DrawContext::PatchArray const & patc
g_pd3dDeviceContext->IASetInputLayout(g_pInputLayout);
g_pd3dDeviceContext->VSSetShader(config->vertexShader, NULL, 0);
g_pd3dDeviceContext->VSSetShader(config->GetVertexShader(), NULL, 0);
g_pd3dDeviceContext->VSSetConstantBuffers(0, 1, &g_pcbPerFrame);
g_pd3dDeviceContext->HSSetShader(config->hullShader, NULL, 0);
g_pd3dDeviceContext->HSSetShader(config->GetHullShader(), NULL, 0);
g_pd3dDeviceContext->HSSetConstantBuffers(0, 1, &g_pcbPerFrame);
g_pd3dDeviceContext->HSSetConstantBuffers(1, 1, &g_pcbTessellation);
g_pd3dDeviceContext->DSSetShader(config->domainShader, NULL, 0);
g_pd3dDeviceContext->DSSetShader(config->GetDomainShader(), NULL, 0);
g_pd3dDeviceContext->DSSetConstantBuffers(0, 1, &g_pcbPerFrame);
g_pd3dDeviceContext->DSSetConstantBuffers(3, 1, &g_pcbConfig);
g_pd3dDeviceContext->GSSetShader(config->geometryShader, NULL, 0);
g_pd3dDeviceContext->GSSetShader(config->GetGeometryShader(), NULL, 0);
g_pd3dDeviceContext->GSSetConstantBuffers(0, 1, &g_pcbPerFrame);
g_pd3dDeviceContext->PSSetShader(config->pixelShader, NULL, 0);
g_pd3dDeviceContext->PSSetShader(config->GetPixelShader(), NULL, 0);
g_pd3dDeviceContext->PSSetConstantBuffers(0, 1, &g_pcbPerFrame);
g_pd3dDeviceContext->PSSetConstantBuffers(2, 1, &g_pcbLighting);
g_pd3dDeviceContext->PSSetConstantBuffers(3, 1, &g_pcbConfig);
@ -952,6 +969,8 @@ bindProgram(Effect effect, OpenSubdiv::Osd::DrawContext::PatchArray const & patc
3, 1, &g_mesh->GetDrawContext()->patchParamBufferSRV);
g_pd3dDeviceContext->GSSetShaderResources(
3, 1, &g_mesh->GetDrawContext()->patchParamBufferSRV);
g_pd3dDeviceContext->PSSetShaderResources(
3, 1, &g_mesh->GetDrawContext()->patchParamBufferSRV);
}
g_pd3dDeviceContext->PSSetShaderResources(4, 1, g_osdPTexImage->GetTexelsSRV());

View File

@ -141,21 +141,31 @@ void vs_main( in InputVertex input,
// Geometry Shader
// ---------------------------------------------------------------------------
OutputVertex
outputVertex(OutputVertex input, float3 normal)
struct GS_OUT
{
OutputVertex v = input;
v.normal = normal;
return v;
OutputVertex v;
uint primitiveID : SV_PrimitiveID;
};
GS_OUT
outputVertex(OutputVertex input, float3 normal, uint primitiveID)
{
GS_OUT gsout;
gsout.v = input;
gsout.v.normal = normal;
gsout.primitiveID = primitiveID;
return gsout;
}
OutputVertex
outputVertex(OutputVertex input, float3 normal, float4 patchCoord)
GS_OUT
outputVertex(OutputVertex input, float3 normal, float4 patchCoord, uint primitiveID)
{
OutputVertex v = input;
v.normal = normal;
v.patchCoord = patchCoord;
return v;
GS_OUT gsout;
gsout.v = input;
gsout.v.normal = normal;
gsout.v.patchCoord = patchCoord;
gsout.primitiveID = primitiveID;
return gsout;
}
#if defined(GEOMETRY_OUT_WIRE) || defined(GEOMETRY_OUT_LINE)
@ -175,36 +185,37 @@ float edgeDistance(float2 p, float2 p0, float2 p1)
(p.y - p0.y) * (p1.x - p0.x)) / length(p1.xy - p0.xy);
}
OutputVertex
GS_OUT
outputWireVertex(OutputVertex input, float3 normal,
int index, float2 edgeVerts[EDGE_VERTS])
int index, float2 edgeVerts[EDGE_VERTS], uint primitiveID)
{
OutputVertex v = input;
v.normal = normal;
GS_OUT gsout;
gsout.v = input;
gsout.v.normal = normal;
v.edgeDistance[0] =
gsout.v.edgeDistance[0] =
edgeDistance(edgeVerts[index], edgeVerts[0], edgeVerts[1]);
v.edgeDistance[1] =
gsout.v.edgeDistance[1] =
edgeDistance(edgeVerts[index], edgeVerts[1], edgeVerts[2]);
#ifdef PRIM_TRI
v.edgeDistance[2] =
gsout.v.edgeDistance[2] =
edgeDistance(edgeVerts[index], edgeVerts[2], edgeVerts[0]);
#endif
#ifdef PRIM_QUAD
v.edgeDistance[2] =
gsout.v.edgeDistance[2] =
edgeDistance(edgeVerts[index], edgeVerts[2], edgeVerts[3]);
v.edgeDistance[3] =
gsout.v.edgeDistance[3] =
edgeDistance(edgeVerts[index], edgeVerts[3], edgeVerts[0]);
#endif
return v;
gsout.primitiveID = primitiveID;
return gsout;
}
#endif
#ifdef PRIM_QUAD
[maxvertexcount(6)]
void gs_main( lineadj OutputVertex input[4],
inout TriangleStream<OutputVertex> triStream,
inout TriangleStream<GS_OUT> triStream,
uint primitiveID : SV_PrimitiveID)
{
float3 A = (input[0].position - input[1].position).xyz;
@ -219,19 +230,20 @@ void gs_main( lineadj OutputVertex input[4],
patchCoord[2] = GeneratePatchCoord(float2(1, 1), primitiveID);
patchCoord[3] = GeneratePatchCoord(float2(0, 1), primitiveID);
triStream.Append(outputVertex(input[0], n0, patchCoord[0]));
triStream.Append(outputVertex(input[1], n0, patchCoord[1]));
triStream.Append(outputVertex(input[3], n0, patchCoord[3]));
triStream.Append(outputVertex(input[0], n0, patchCoord[0], primitiveID));
triStream.Append(outputVertex(input[1], n0, patchCoord[1], primitiveID));
triStream.Append(outputVertex(input[3], n0, patchCoord[3], primitiveID));
triStream.RestartStrip();
triStream.Append(outputVertex(input[3], n0, patchCoord[3]));
triStream.Append(outputVertex(input[1], n0, patchCoord[1]));
triStream.Append(outputVertex(input[2], n0, patchCoord[2]));
triStream.Append(outputVertex(input[3], n0, patchCoord[3], primitiveID));
triStream.Append(outputVertex(input[1], n0, patchCoord[1], primitiveID));
triStream.Append(outputVertex(input[2], n0, patchCoord[2], primitiveID));
triStream.RestartStrip();
}
#else // PRIM_TRI
[maxvertexcount(3)]
void gs_main( triangle OutputVertex input[3],
inout TriangleStream<OutputVertex> triStream )
inout TriangleStream<GS_OUT> triStream,
uint primitiveID : SV_PrimitiveID)
{
float4 position[3];
float4 patchCoord[3];
@ -265,13 +277,13 @@ void gs_main( triangle OutputVertex input[3],
edgeVerts[1] = input[1].positionOut.xy / input[1].positionOut.w;
edgeVerts[2] = input[2].positionOut.xy / input[2].positionOut.w;
triStream.Append(outputWireVertex(input[0], normal[0], 0, edgeVerts));
triStream.Append(outputWireVertex(input[1], normal[1], 1, edgeVerts));
triStream.Append(outputWireVertex(input[2], normal[2], 2, edgeVerts));
triStream.Append(outputWireVertex(input[0], normal[0], 0, edgeVerts, primitiveID));
triStream.Append(outputWireVertex(input[1], normal[1], 1, edgeVerts, primitiveID));
triStream.Append(outputWireVertex(input[2], normal[2], 2, edgeVerts, primitiveID));
#else
triStream.Append(outputVertex(input[0], normal[0]));
triStream.Append(outputVertex(input[1], normal[1]));
triStream.Append(outputVertex(input[2], normal[2]));
triStream.Append(outputVertex(input[0], normal[0], primitiveID));
triStream.Append(outputVertex(input[1], normal[1], primitiveID));
triStream.Append(outputVertex(input[2], normal[2], primitiveID));
#endif
}
@ -373,8 +385,88 @@ Texture2DArray textureSpecular_Data : register(t10);
Buffer<uint> textureSpecular_Packing : register(t11);
#endif
float4
getAdaptivePatchColor(int3 patchParam, float sharpness)
{
const float4 patchColors[7*6] = {
float4(1.0f, 1.0f, 1.0f, 1.0f), // regular
float4(0.0f, 1.0f, 1.0f, 1.0f), // regular pattern 0
float4(0.0f, 0.5f, 1.0f, 1.0f), // regular pattern 1
float4(0.0f, 0.5f, 0.5f, 1.0f), // regular pattern 2
float4(0.5f, 0.0f, 1.0f, 1.0f), // regular pattern 3
float4(1.0f, 0.5f, 1.0f, 1.0f), // regular pattern 4
float4(1.0f, 0.5f, 0.5f, 1.0f), // single crease
float4(1.0f, 0.70f, 0.6f, 1.0f), // single crease pattern 0
float4(1.0f, 0.65f, 0.6f, 1.0f), // single crease pattern 1
float4(1.0f, 0.60f, 0.6f, 1.0f), // single crease pattern 2
float4(1.0f, 0.55f, 0.6f, 1.0f), // single crease pattern 3
float4(1.0f, 0.50f, 0.6f, 1.0f), // single crease pattern 4
float4(0.8f, 0.0f, 0.0f, 1.0f), // boundary
float4(0.0f, 0.0f, 0.75f, 1.0f), // boundary pattern 0
float4(0.0f, 0.2f, 0.75f, 1.0f), // boundary pattern 1
float4(0.0f, 0.4f, 0.75f, 1.0f), // boundary pattern 2
float4(0.0f, 0.6f, 0.75f, 1.0f), // boundary pattern 3
float4(0.0f, 0.8f, 0.75f, 1.0f), // boundary pattern 4
float4(0.0f, 1.0f, 0.0f, 1.0f), // corner
float4(0.25f, 0.25f, 0.25f, 1.0f), // corner pattern 0
float4(0.25f, 0.25f, 0.25f, 1.0f), // corner pattern 1
float4(0.25f, 0.25f, 0.25f, 1.0f), // corner pattern 2
float4(0.25f, 0.25f, 0.25f, 1.0f), // corner pattern 3
float4(0.25f, 0.25f, 0.25f, 1.0f), // corner pattern 4
float4(1.0f, 1.0f, 0.0f, 1.0f), // gregory
float4(1.0f, 1.0f, 0.0f, 1.0f), // gregory
float4(1.0f, 1.0f, 0.0f, 1.0f), // gregory
float4(1.0f, 1.0f, 0.0f, 1.0f), // gregory
float4(1.0f, 1.0f, 0.0f, 1.0f), // gregory
float4(1.0f, 1.0f, 0.0f, 1.0f), // gregory
float4(1.0f, 0.5f, 0.0f, 1.0f), // gregory boundary
float4(1.0f, 0.5f, 0.0f, 1.0f), // gregory boundary
float4(1.0f, 0.5f, 0.0f, 1.0f), // gregory boundary
float4(1.0f, 0.5f, 0.0f, 1.0f), // gregory boundary
float4(1.0f, 0.5f, 0.0f, 1.0f), // gregory boundary
float4(1.0f, 0.5f, 0.0f, 1.0f), // gregory boundary
float4(1.0f, 0.7f, 0.3f, 1.0f), // gregory basis
float4(1.0f, 0.7f, 0.3f, 1.0f), // gregory basis
float4(1.0f, 0.7f, 0.3f, 1.0f), // gregory basis
float4(1.0f, 0.7f, 0.3f, 1.0f), // gregory basis
float4(1.0f, 0.7f, 0.3f, 1.0f), // gregory basis
float4(1.0f, 0.7f, 0.3f, 1.0f) // gregory basis
};
int patchType = 0;
#if defined OSD_PATCH_GREGORY
patchType = 4;
#elif defined OSD_PATCH_GREGORY_BOUNDARY
patchType = 5;
#elif defined OSD_PATCH_GREGORY_BASIS
patchType = 6;
#endif
int edgeCount = countbits(OsdGetPatchBoundaryMask(patchParam));
if (edgeCount == 1) {
patchType = 2; // BOUNDARY
}
if (edgeCount == 2) {
patchType = 3; // CORNER
}
int pattern = countbits(OsdGetPatchTransitionMask(patchParam));
#ifdef OSD_PATCH_ENABLE_SINGLE_CREASE
if (sharpness > 0) pattern += 6;
#endif
return patchColors[6*patchType + pattern];
}
void
ps_main(in OutputVertex input,
uint primitiveID : SV_PrimitiveID,
out float4 outColor : SV_Target )
{
// ------------ normal ---------------
@ -425,7 +517,9 @@ ps_main(in OutputVertex input,
textureImage_Data,
textureImage_Packing);
#elif defined(COLOR_PATCHTYPE)
float4 texColor = edgeColor(lighting(overrideColor, input.position.xyz, normal, 0),
float4 patchColor = getAdaptivePatchColor(
OsdGetPatchParam(OsdGetPatchIndex(primitiveID)), 0);
float4 texColor = edgeColor(lighting(patchColor, input.position.xyz, normal, 0),
input.edgeDistance);
outColor = texColor;
return;
@ -446,9 +540,9 @@ ps_main(in OutputVertex input,
// ------------ occlusion ---------------
#ifdef USE_PTEX_OCCLUSION
float occ = PtexLookup(input.patchCoord,
textureOcclusion_Data,
textureOcclusion_Packing).x;
float occ = PtexMipmapLookup(input.patchCoord, mipmapBias,
textureOcclusion_Data,
textureOcclusion_Packing).x;
#else
float occ = 0.0;
#endif
@ -456,9 +550,9 @@ ps_main(in OutputVertex input,
// ------------ specular ---------------
#ifdef USE_PTEX_SPECULAR
float specular = PtexLookup(input.patchCoord,
textureSpecular_Data,
textureSpecular_Packing).x;
float specular = PtexMipmapLookup(input.patchCoord, mipmapBias,
textureSpecular_Data,
textureSpecular_Packing).x;
#else
float specular = 1.0;
#endif

View File

@ -26,7 +26,6 @@
#include <D3Dcompiler.h>
#include <osd/d3d11DrawContext.h>
#include <osd/d3d11DrawRegistry.h>
#include <far/error.h>
#include <osd/cpuD3D11VertexBuffer.h>
@ -64,8 +63,9 @@ OpenSubdiv::Osd::D3D11MeshInterface *g_mesh;
#include "../common/stopwatch.h"
#include "../common/simple_math.h"
#include "../common/d3d11_hud.h"
#include "../common/patchColors.h"
#include "../common/d3d11ShaderCache.h"
#include <osd/hlslPatchShaderSource.h>
static const char *shaderSource =
#include "shader.gen.h"
;
@ -88,13 +88,10 @@ enum KernelType { kCPU = 0,
kCL = 4,
kDirectCompute = 5 };
enum DisplayStyle { kQuadWire = 0,
kQuadFill = 1,
kQuadLine = 2,
kTriWire = 3,
kTriFill = 4,
kTriLine = 5,
kPoint = 6 };
enum DisplayStyle { kWire = 0,
kShaded,
kWireShaded,
kPoint };
enum HudCheckBox { kHUD_CB_DISPLAY_CAGE_EDGES,
kHUD_CB_DISPLAY_CAGE_VERTS,
@ -114,7 +111,7 @@ int g_frame = 0,
// GUI variables
int g_freeze = 0,
g_wire = 2,
g_displayStyle = kWireShaded,
g_adaptive = 1,
g_singleCreasePatch = 1,
g_drawCageEdges = 1,
@ -461,176 +458,150 @@ struct EffectDesc {
}
};
class EffectDrawRegistry : public OpenSubdiv::Osd::D3D11DrawRegistry<EffectDesc> {
static Effect
GetEffect()
{
return Effect(g_displayStyle,
g_screenSpaceTess,
g_fractionalSpacing,
g_patchCull);
}
protected:
virtual ConfigType *
_CreateDrawConfig(EffectDesc const & desc,
SourceConfigType const * sconfig,
ID3D11Device * pd3dDevice,
ID3D11InputLayout ** ppInputLayout,
D3D11_INPUT_ELEMENT_DESC const * pInputElementDescs,
int numInputElements);
// ---------------------------------------------------------------------------
virtual SourceConfigType *
_CreateDrawSourceConfig(EffectDesc const & desc, ID3D11Device * pd3dDevice);
};
class ShaderCache : public D3D11ShaderCache<EffectDesc> {
public:
virtual D3D11DrawConfig *CreateDrawConfig(EffectDesc const &effectDesc) {
using namespace OpenSubdiv;
EffectDrawRegistry::SourceConfigType *
EffectDrawRegistry::_CreateDrawSourceConfig(
EffectDesc const &effectDesc, ID3D11Device * pd3dDevice) {
D3D11DrawConfig *config = new D3D11DrawConfig();
Effect effect = effectDesc.effect;
Far::PatchDescriptor::Type type = effectDesc.desc.GetType();
SourceConfigType * sconfig =
BaseRegistry::_CreateDrawSourceConfig(effectDesc.desc, pd3dDevice);
// common defines
std::stringstream ss;
sconfig->commonShader.AddDefine("OSD_ENABLE_PATCH_CULL");
sconfig->commonShader.AddDefine("OSD_ENABLE_SCREENSPACE_TESSELLATION");
if (type == Far::PatchDescriptor::QUADS) {
ss << "#define PRIM_QUAD\n";
} else {
ss << "#define PRIM_TRI\n";
}
// legacy gregory patch requires OSD_MAX_VALENCE and OSD_NUM_ELEMENTS defined
if (effectDesc.desc.GetType() == OpenSubdiv::Far::PatchDescriptor::GREGORY or
effectDesc.desc.GetType() == OpenSubdiv::Far::PatchDescriptor::GREGORY_BOUNDARY) {
std::ostringstream ss;
ss << effectDesc.maxValence;
sconfig->commonShader.AddDefine("OSD_MAX_VALENCE", ss.str());
// OSD tessellation controls
if (effectDesc.effect.screenSpaceTess) {
ss << "#define OSD_ENABLE_SCREENSPACE_TESSELLATION\n";
}
if (effectDesc.effect.fractionalSpacing) {
ss << "#define OSD_FRACTIONAL_ODD_SPACING\n";
}
if (effectDesc.effect.patchCull) {
ss << "#define OSD_ENABLE_PATCH_CULL\n";
}
if (g_singleCreasePatch) {
ss << "#define OSD_PATCH_ENABLE_SINGLE_CREASE\n";
}
// for legacy gregory
ss << "#define OSD_MAX_VALENCE " << effectDesc.maxValence << "\n";
ss << "#define OSD_NUM_ELEMENTS " << effectDesc.numElements << "\n";
// display styles
std::string gs_entry =
(type == Far::PatchDescriptor::QUADS ? "gs_quad" : "gs_triangle");
if (effectDesc.desc.IsAdaptive()) gs_entry += "_smooth";
switch (effectDesc.effect.displayStyle) {
case kWire:
ss << "#define GEOMETRY_OUT_WIRE\n";
gs_entry = gs_entry + "_wire";
break;
case kWireShaded:
ss << "#define GEOMETRY_OUT_LINE\n";
gs_entry = gs_entry + "_wire";
break;
case kShaded:
ss << "#define GEOMETRY_OUT_FILL\n";
break;
}
// need for patch color-coding : we need these defines in the fragment shader
if (type == Far::PatchDescriptor::GREGORY) {
ss << "#define OSD_PATCH_GREGORY\n";
} else if (type == Far::PatchDescriptor::GREGORY_BOUNDARY) {
ss << "#define OSD_PATCH_GREGORY_BOUNDARY\n";
} else if (type == Far::PatchDescriptor::GREGORY_BASIS) {
ss << "#define OSD_PATCH_GREGORY_BASIS\n";
}
// include osd PatchCommon
ss << Osd::HLSLPatchShaderSource::GetCommonShaderSource();
std::string common = ss.str();
ss.str("");
ss << effectDesc.numElements;
sconfig->commonShader.AddDefine("OSD_NUM_ELEMENTS", ss.str());
}
// input layout
const D3D11_INPUT_ELEMENT_DESC hInElementDesc[] = {
{ "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 },
{ "NORMAL", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 4*3, D3D11_INPUT_PER_VERTEX_DATA, 0 }
};
bool smoothNormals = false;
if (effectDesc.desc.GetType() == OpenSubdiv::Far::PatchDescriptor::QUADS ||
effectDesc.desc.GetType() == OpenSubdiv::Far::PatchDescriptor::TRIANGLES) {
sconfig->vertexShader.source = shaderSource;
sconfig->vertexShader.target = "vs_5_0";
sconfig->vertexShader.entry = "vs_main";
} else if (effectDesc.desc.GetType() == OpenSubdiv::Far::PatchDescriptor::TRIANGLES) {
if (effect.displayStyle == kQuadWire) effect.displayStyle = kTriWire;
if (effect.displayStyle == kQuadFill) effect.displayStyle = kTriFill;
if (effect.displayStyle == kQuadLine) effect.displayStyle = kTriLine;
smoothNormals = true;
} else {
// adaptive
if (effect.displayStyle == kQuadWire) effect.displayStyle = kTriWire;
if (effect.displayStyle == kQuadFill) effect.displayStyle = kTriFill;
if (effect.displayStyle == kQuadLine) effect.displayStyle = kTriLine;
smoothNormals = true;
sconfig->vertexShader.source = shaderSource + sconfig->vertexShader.source;
sconfig->hullShader.source = shaderSource + sconfig->hullShader.source;
sconfig->domainShader.source = shaderSource + sconfig->domainShader.source;
}
assert(sconfig);
sconfig->geometryShader.source = shaderSource;
sconfig->geometryShader.target = "gs_5_0";
sconfig->pixelShader.source = shaderSource;
sconfig->pixelShader.target = "ps_5_0";
if (effect.screenSpaceTess) {
sconfig->commonShader.AddDefine("OSD_ENABLE_SCREENSPACE_TESSELLATION");
}
if (effect.fractionalSpacing) {
sconfig->commonShader.AddDefine("OSD_FRACTIONAL_ODD_SPACING");
}
if (effect.patchCull) {
sconfig->commonShader.AddDefine("OSD_ENABLE_PATCH_CULL");
}
// vertex shader
ss << common
<< shaderSource
<< Osd::HLSLPatchShaderSource::GetVertexShaderSource(type);
if (effectDesc.desc.IsAdaptive()) {
config->CompileVertexShader("vs_5_0", "vs_main_patches", ss.str(),
&g_pInputLayout,
hInElementDesc,
ARRAYSIZE(hInElementDesc),
g_pd3dDevice);
} else {
config->CompileVertexShader("vs_5_0", "vs_main",
ss.str(),
&g_pInputLayout,
hInElementDesc,
ARRAYSIZE(hInElementDesc),
g_pd3dDevice);
}
ss.str("");
switch (effect.displayStyle) {
case kQuadWire:
sconfig->geometryShader.entry = "gs_quad_wire";
sconfig->geometryShader.AddDefine("PRIM_QUAD");
sconfig->geometryShader.AddDefine("GEOMETRY_OUT_WIRE");
sconfig->pixelShader.entry = "ps_main";
sconfig->pixelShader.AddDefine("PRIM_QUAD");
sconfig->pixelShader.AddDefine("GEOMETRY_OUT_WIRE");
break;
case kQuadFill:
sconfig->geometryShader.entry = "gs_quad";
sconfig->geometryShader.AddDefine("PRIM_QUAD");
sconfig->geometryShader.AddDefine("GEOMETRY_OUT_FILL");
sconfig->pixelShader.entry = "ps_main";
sconfig->pixelShader.AddDefine("PRIM_QUAD");
sconfig->pixelShader.AddDefine("GEOMETRY_OUT_FILL");
break;
case kQuadLine:
sconfig->geometryShader.entry = "gs_quad_wire";
sconfig->geometryShader.AddDefine("PRIM_QUAD");
sconfig->geometryShader.AddDefine("GEOMETRY_OUT_LINE");
sconfig->pixelShader.entry = "ps_main";
sconfig->pixelShader.AddDefine("PRIM_QUAD");
sconfig->pixelShader.AddDefine("GEOMETRY_OUT_LINE");
break;
case kTriWire:
sconfig->geometryShader.entry =
smoothNormals ? "gs_triangle_smooth_wire" : "gs_triangle_wire";
sconfig->geometryShader.AddDefine("PRIM_TRI");
sconfig->geometryShader.AddDefine("GEOMETRY_OUT_WIRE");
sconfig->pixelShader.entry = "ps_main";
sconfig->pixelShader.AddDefine("PRIM_TRI");
sconfig->pixelShader.AddDefine("GEOMETRY_OUT_WIRE");
break;
case kTriFill:
sconfig->geometryShader.entry =
smoothNormals ? "gs_triangle_smooth" : "gs_triangle";
sconfig->geometryShader.AddDefine("PRIM_TRI");
sconfig->geometryShader.AddDefine("GEOMETRY_OUT_FILL");
sconfig->pixelShader.entry = "ps_main";
sconfig->pixelShader.AddDefine("PRIM_TRI");
sconfig->pixelShader.AddDefine("GEOMETRY_OUT_FILL");
break;
case kTriLine:
sconfig->geometryShader.entry =
smoothNormals ? "gs_triangle_smooth_wire" : "gs_triangle_wire";
sconfig->geometryShader.AddDefine("PRIM_TRI");
sconfig->geometryShader.AddDefine("GEOMETRY_OUT_LINE");
sconfig->pixelShader.entry = "ps_main";
sconfig->pixelShader.AddDefine("PRIM_TRI");
sconfig->pixelShader.AddDefine("GEOMETRY_OUT_LINE");
break;
case kPoint:
sconfig->geometryShader.entry = "gs_point";
sconfig->pixelShader.entry = "ps_main_point";
break;
}
if (effectDesc.desc.IsAdaptive()) {
// hull shader
ss << common
<< shaderSource
<< Osd::HLSLPatchShaderSource::GetHullShaderSource(type);
config->CompileHullShader("hs_5_0", "hs_main_patches", ss.str(),
g_pd3dDevice);
ss.str("");
return sconfig;
}
// domain shader
ss << common
<< shaderSource
<< Osd::HLSLPatchShaderSource::GetDomainShaderSource(type);
config->CompileDomainShader("ds_5_0", "ds_main_patches", ss.str(),
g_pd3dDevice);
ss.str("");
}
EffectDrawRegistry::ConfigType *
EffectDrawRegistry::_CreateDrawConfig(
DescType const & desc,
SourceConfigType const * sconfig,
ID3D11Device * pd3dDevice,
ID3D11InputLayout ** ppInputLayout,
D3D11_INPUT_ELEMENT_DESC const * pInputElementDescs,
int numInputElements) {
// geometry shader
ss << common
<< shaderSource;
config->CompileGeometryShader("gs_5_0", gs_entry,
ss.str(),
g_pd3dDevice);
ss.str("");
ConfigType * config = BaseRegistry::_CreateDrawConfig(desc.desc, sconfig,
pd3dDevice, ppInputLayout, pInputElementDescs, numInputElements);
assert(config);
// pixel shader
ss << common
<< shaderSource;
config->CompilePixelShader("ps_5_0", "ps_main", ss.str(),
g_pd3dDevice);
ss.str("");
return config;
}
return config;
};
};
EffectDrawRegistry effectRegistry;
static Effect
GetEffect() {
DisplayStyle style;
if (g_scheme == kLoop) {
style = (g_wire == 0 ? kTriWire : (g_wire == 1 ? kTriFill : kTriLine));
} else {
style = (g_wire == 0 ? style=kQuadWire : (g_wire == 1 ? kQuadFill : kQuadLine));
}
return Effect(style, g_screenSpaceTess, g_fractionalSpacing, g_patchCull);
}
ShaderCache g_shaderCache;
//------------------------------------------------------------------------------
static void
@ -649,16 +620,7 @@ bindProgram(Effect effect, OpenSubdiv::Osd::DrawContext::PatchArray const & patc
effectDesc.numElements = numElements;
}
// input layout
const D3D11_INPUT_ELEMENT_DESC hInElementDesc[] = {
{ "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 },
{ "NORMAL", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 4*3, D3D11_INPUT_PER_VERTEX_DATA, 0 }
};
EffectDrawRegistry::ConfigType *
config = effectRegistry.GetDrawConfig(
effectDesc, g_pd3dDevice,
&g_pInputLayout, hInElementDesc, ARRAYSIZE(hInElementDesc));
D3D11DrawConfig *config = g_shaderCache.GetDrawConfig(effectDesc);
assert(g_pInputLayout);
@ -758,34 +720,28 @@ bindProgram(Effect effect, OpenSubdiv::Osd::DrawContext::PatchArray const & patc
g_pd3dDeviceContext->Map(g_pcbMaterial, 0, D3D11_MAP_WRITE_DISCARD, 0, &MappedResource);
Material * pData = ( Material* )MappedResource.pData;
float const * patchColor;
if (g_displayPatchColor and g_mesh->GetDrawContext()->IsAdaptive()) {
patchColor = getAdaptivePatchColor( patch.GetDescriptor() );
} else {
static float const uniformColor[4] = {0.13f, 0.13f, 0.61f, 1.0f};
patchColor = uniformColor;
}
memcpy(pData->color, patchColor, 4*sizeof(float));
static float const uniformColor[4] = {0.13f, 0.13f, 0.61f, 1.0f};
memcpy(pData->color, uniformColor, 4*sizeof(float));
g_pd3dDeviceContext->Unmap( g_pcbMaterial, 0 );
}
g_pd3dDeviceContext->IASetInputLayout(g_pInputLayout);
g_pd3dDeviceContext->VSSetShader(config->vertexShader, NULL, 0);
g_pd3dDeviceContext->VSSetShader(config->GetVertexShader(), NULL, 0);
g_pd3dDeviceContext->VSSetConstantBuffers(0, 1, &g_pcbPerFrame);
g_pd3dDeviceContext->HSSetShader(config->hullShader, NULL, 0);
g_pd3dDeviceContext->HSSetShader(config->GetHullShader(), NULL, 0);
g_pd3dDeviceContext->HSSetConstantBuffers(0, 1, &g_pcbPerFrame);
g_pd3dDeviceContext->HSSetConstantBuffers(1, 1, &g_pcbTessellation);
g_pd3dDeviceContext->DSSetShader(config->domainShader, NULL, 0);
g_pd3dDeviceContext->DSSetShader(config->GetDomainShader(), NULL, 0);
g_pd3dDeviceContext->DSSetConstantBuffers(0, 1, &g_pcbPerFrame);
g_pd3dDeviceContext->GSSetShader(config->geometryShader, NULL, 0);
g_pd3dDeviceContext->GSSetShader(config->GetGeometryShader(), NULL, 0);
g_pd3dDeviceContext->GSSetConstantBuffers(0, 1, &g_pcbPerFrame);
g_pd3dDeviceContext->PSSetShader(config->pixelShader, NULL, 0);
g_pd3dDeviceContext->PSSetShader(config->GetPixelShader(), NULL, 0);
g_pd3dDeviceContext->PSSetConstantBuffers(0, 1, &g_pcbPerFrame);
g_pd3dDeviceContext->PSSetConstantBuffers(2, 1, &g_pcbLighting);
g_pd3dDeviceContext->PSSetConstantBuffers(3, 1, &g_pcbMaterial);
@ -804,6 +760,8 @@ bindProgram(Effect effect, OpenSubdiv::Osd::DrawContext::PatchArray const & patc
3, 1, &g_mesh->GetDrawContext()->patchParamBufferSRV);
g_pd3dDeviceContext->DSSetShaderResources(
3, 1, &g_mesh->GetDrawContext()->patchParamBufferSRV);
g_pd3dDeviceContext->PSSetShaderResources(
3, 1, &g_mesh->GetDrawContext()->patchParamBufferSRV);
}
}
@ -1025,8 +983,8 @@ keyboard(char key) {
//------------------------------------------------------------------------------
static void
callbackWireframe(int b) {
g_wire = b;
callbackDisplayStyle(int b) {
g_displayStyle = b;
}
static void
@ -1165,10 +1123,10 @@ initHUD() {
#endif
g_hud->AddPullDownButton(compute_pulldown, "HLSL Compute", kDirectCompute);
int shading_pulldown = g_hud->AddPullDown("Shading (W)", 200, 10, 250, callbackWireframe, 'W');
g_hud->AddPullDownButton(shading_pulldown, "Wire", 0, g_wire==0);
g_hud->AddPullDownButton(shading_pulldown, "Shaded", 1, g_wire==1);
g_hud->AddPullDownButton(shading_pulldown, "Wire+Shaded", 2, g_wire==2);
int shading_pulldown = g_hud->AddPullDown("Shading (W)", 200, 10, 250, callbackDisplayStyle, 'W');
g_hud->AddPullDownButton(shading_pulldown, "Wire", 0, g_displayStyle==kWire);
g_hud->AddPullDownButton(shading_pulldown, "Shaded", 1, g_displayStyle==kShaded);
g_hud->AddPullDownButton(shading_pulldown, "Wire+Shaded", 2, g_displayStyle==kWireShaded);
// g_hud->AddCheckBox("Cage Edges (H)", true, 10, 10, callbackDisplayCageEdges, 0, 'H');
// g_hud->AddCheckBox("Cage Verts (J)", false, 10, 30, callbackDisplayCageVertices, 0, 'J');

View File

@ -79,12 +79,20 @@ void vs_main( in InputVertex input,
// Geometry Shader
// ---------------------------------------------------------------------------
OutputVertex
outputVertex(OutputVertex input, float3 normal)
struct GS_OUT
{
OutputVertex v = input;
v.normal = normal;
return v;
OutputVertex v;
uint primitiveID : SV_PrimitiveID;
};
GS_OUT
outputVertex(OutputVertex input, float3 normal, uint primitiveID)
{
GS_OUT gsout;
gsout.v = input;
gsout.v.normal = normal;
gsout.primitiveID = primitiveID;
return gsout;
}
#if defined(GEOMETRY_OUT_WIRE) || defined(GEOMETRY_OUT_LINE)
@ -104,35 +112,37 @@ float edgeDistance(float2 p, float2 p0, float2 p1)
(p.y - p0.y) * (p1.x - p0.x)) / length(p1.xy - p0.xy);
}
OutputVertex
GS_OUT
outputWireVertex(OutputVertex input, float3 normal,
int index, float2 edgeVerts[EDGE_VERTS])
int index, float2 edgeVerts[EDGE_VERTS], uint primitiveID)
{
OutputVertex v = input;
v.normal = normal;
GS_OUT gsout;
gsout.v = input;
gsout.v.normal = normal;
v.edgeDistance[0] =
gsout.v.edgeDistance[0] =
edgeDistance(edgeVerts[index], edgeVerts[0], edgeVerts[1]);
v.edgeDistance[1] =
gsout.v.edgeDistance[1] =
edgeDistance(edgeVerts[index], edgeVerts[1], edgeVerts[2]);
#ifdef PRIM_TRI
v.edgeDistance[2] =
gsout.v.edgeDistance[2] =
edgeDistance(edgeVerts[index], edgeVerts[2], edgeVerts[0]);
#endif
#ifdef PRIM_QUAD
v.edgeDistance[2] =
gsout.v.edgeDistance[2] =
edgeDistance(edgeVerts[index], edgeVerts[2], edgeVerts[3]);
v.edgeDistance[3] =
gsout.v.edgeDistance[3] =
edgeDistance(edgeVerts[index], edgeVerts[3], edgeVerts[0]);
#endif
return v;
gsout.primitiveID = primitiveID;
return gsout;
}
#endif
[maxvertexcount(6)]
void gs_quad( lineadj OutputVertex input[4],
inout TriangleStream<OutputVertex> triStream )
uint primitiveID : SV_PrimitiveID,
inout TriangleStream<GS_OUT> triStream )
{
float3 A = (input[0].position - input[1].position).xyz;
float3 B = (input[3].position - input[1].position).xyz;
@ -140,13 +150,13 @@ void gs_quad( lineadj OutputVertex input[4],
float3 n0 = normalize(cross(B, A));
triStream.Append(outputVertex(input[0], n0));
triStream.Append(outputVertex(input[1], n0));
triStream.Append(outputVertex(input[3], n0));
triStream.Append(outputVertex(input[0], n0, primitiveID));
triStream.Append(outputVertex(input[1], n0, primitiveID));
triStream.Append(outputVertex(input[3], n0, primitiveID));
triStream.RestartStrip();
triStream.Append(outputVertex(input[3], n0));
triStream.Append(outputVertex(input[1], n0));
triStream.Append(outputVertex(input[2], n0));
triStream.Append(outputVertex(input[3], n0, primitiveID));
triStream.Append(outputVertex(input[1], n0, primitiveID));
triStream.Append(outputVertex(input[2], n0, primitiveID));
triStream.RestartStrip();
}
@ -154,7 +164,8 @@ void gs_quad( lineadj OutputVertex input[4],
#ifdef PRIM_QUAD
[maxvertexcount(6)]
void gs_quad_wire( lineadj OutputVertex input[4],
inout TriangleStream<OutputVertex> triStream )
uint primitiveID : SV_PrimitiveID,
inout TriangleStream<GS_OUT> triStream )
{
float3 A = (input[0].position - input[1].position).xyz;
float3 B = (input[3].position - input[1].position).xyz;
@ -168,13 +179,13 @@ void gs_quad_wire( lineadj OutputVertex input[4],
edgeVerts[2] = input[2].positionOut.xy / input[2].positionOut.w;
edgeVerts[3] = input[3].positionOut.xy / input[3].positionOut.w;
triStream.Append(outputWireVertex(input[0], n0, 0, edgeVerts));
triStream.Append(outputWireVertex(input[1], n0, 1, edgeVerts));
triStream.Append(outputWireVertex(input[3], n0, 3, edgeVerts));
triStream.Append(outputWireVertex(input[0], n0, 0, edgeVerts, primitiveID));
triStream.Append(outputWireVertex(input[1], n0, 1, edgeVerts, primitiveID));
triStream.Append(outputWireVertex(input[3], n0, 3, edgeVerts, primitiveID));
triStream.RestartStrip();
triStream.Append(outputWireVertex(input[3], n0, 3, edgeVerts));
triStream.Append(outputWireVertex(input[1], n0, 1, edgeVerts));
triStream.Append(outputWireVertex(input[2], n0, 2, edgeVerts));
triStream.Append(outputWireVertex(input[3], n0, 3, edgeVerts, primitiveID));
triStream.Append(outputWireVertex(input[1], n0, 1, edgeVerts, primitiveID));
triStream.Append(outputWireVertex(input[2], n0, 2, edgeVerts, primitiveID));
triStream.RestartStrip();
}
#endif
@ -182,32 +193,35 @@ void gs_quad_wire( lineadj OutputVertex input[4],
[maxvertexcount(3)]
void gs_triangle( triangle OutputVertex input[3],
inout TriangleStream<OutputVertex> triStream )
uint primitiveID : SV_PrimitiveID,
inout TriangleStream<GS_OUT> triStream )
{
float3 A = (input[0].position - input[1].position).xyz;
float3 B = (input[2].position - input[1].position).xyz;
float3 n0 = normalize(cross(B, A));
triStream.Append(outputVertex(input[0], n0));
triStream.Append(outputVertex(input[1], n0));
triStream.Append(outputVertex(input[2], n0));
triStream.Append(outputVertex(input[0], n0, primitiveID));
triStream.Append(outputVertex(input[1], n0, primitiveID));
triStream.Append(outputVertex(input[2], n0, primitiveID));
}
[maxvertexcount(3)]
void gs_triangle_smooth( triangle OutputVertex input[3],
inout TriangleStream<OutputVertex> triStream )
uint primitiveID : SV_PrimitiveID,
inout TriangleStream<GS_OUT> triStream )
{
triStream.Append(outputVertex(input[0], input[0].normal));
triStream.Append(outputVertex(input[1], input[1].normal));
triStream.Append(outputVertex(input[2], input[2].normal));
triStream.Append(outputVertex(input[0], input[0].normal, primitiveID));
triStream.Append(outputVertex(input[1], input[1].normal, primitiveID));
triStream.Append(outputVertex(input[2], input[2].normal, primitiveID));
}
#if defined(GEOMETRY_OUT_WIRE) || defined(GEOMETRY_OUT_LINE)
#ifdef PRIM_TRI
[maxvertexcount(3)]
void gs_triangle_wire( triangle OutputVertex input[3],
inout TriangleStream<OutputVertex> triStream )
uint primitiveID : SV_PrimitiveID,
inout TriangleStream<GS_OUT> triStream )
{
float3 A = (input[0].position - input[1].position).xyz;
float3 B = (input[2].position - input[1].position).xyz;
@ -219,23 +233,24 @@ void gs_triangle_wire( triangle OutputVertex input[3],
edgeVerts[1] = input[1].positionOut.xy / input[1].positionOut.w;
edgeVerts[2] = input[2].positionOut.xy / input[2].positionOut.w;
triStream.Append(outputWireVertex(input[0], n0, 0, edgeVerts));
triStream.Append(outputWireVertex(input[1], n0, 1, edgeVerts));
triStream.Append(outputWireVertex(input[2], n0, 2, edgeVerts));
triStream.Append(outputWireVertex(input[0], n0, 0, edgeVerts, primitiveID));
triStream.Append(outputWireVertex(input[1], n0, 1, edgeVerts, primitiveID));
triStream.Append(outputWireVertex(input[2], n0, 2, edgeVerts, primitiveID));
}
[maxvertexcount(3)]
void gs_triangle_smooth_wire( triangle OutputVertex input[3],
inout TriangleStream<OutputVertex> triStream )
uint primitiveID : SV_PrimitiveID,
inout TriangleStream<GS_OUT> triStream )
{
float2 edgeVerts[3];
edgeVerts[0] = input[0].positionOut.xy / input[0].positionOut.w;
edgeVerts[1] = input[1].positionOut.xy / input[1].positionOut.w;
edgeVerts[2] = input[2].positionOut.xy / input[2].positionOut.w;
triStream.Append(outputWireVertex(input[0], input[0].normal, 0, edgeVerts));
triStream.Append(outputWireVertex(input[1], input[1].normal, 1, edgeVerts));
triStream.Append(outputWireVertex(input[2], input[2].normal, 2, edgeVerts));
triStream.Append(outputWireVertex(input[0], input[0].normal, 0, edgeVerts, primitiveID));
triStream.Append(outputWireVertex(input[1], input[1].normal, 1, edgeVerts, primitiveID));
triStream.Append(outputWireVertex(input[2], input[2].normal, 2, edgeVerts, primitiveID));
}
#endif
#endif
@ -273,7 +288,7 @@ cbuffer Material : register( b3 ){
}
float4
lighting(float3 Peye, float3 Neye)
lighting(float4 diffuse, float3 Peye, float3 Neye)
{
float4 color = float4(0.0, 0.0, 0.0, 0.0);
//float4 material = float4(0.4, 0.4, 0.8, 1);
@ -292,8 +307,8 @@ lighting(float3 Peye, float3 Neye)
float d = max(0.0, dot(n, l));
float s = pow(max(0.0, dot(n, h)), 500.0f);
color += lightSource[i].ambient * materialColor
+ d * lightSource[i].diffuse * materialColor
color += lightSource[i].ambient
+ d * lightSource[i].diffuse * diffuse
+ s * lightSource[i].specular;
}
@ -319,7 +334,8 @@ edgeColor(float4 Cfill, float4 edgeDistance)
min(min(edgeDistance[0], edgeDistance[1]),
min(edgeDistance[2], edgeDistance[3]));
#endif
float4 Cedge = float4(1.0, 1.0, 0.0, 1.0);
float v = 0.5;
float4 Cedge = float4(Cfill.r*v, Cfill.g*v, Cfill.b*v, 1);
float p = exp2(-2 * d * d);
#if defined(GEOMETRY_OUT_WIRE)
@ -331,17 +347,104 @@ edgeColor(float4 Cfill, float4 edgeDistance)
return Cfill;
}
float4
getAdaptivePatchColor(int3 patchParam, float sharpness)
{
const float4 patchColors[7*6] = {
float4(1.0f, 1.0f, 1.0f, 1.0f), // regular
float4(0.0f, 1.0f, 1.0f, 1.0f), // regular pattern 0
float4(0.0f, 0.5f, 1.0f, 1.0f), // regular pattern 1
float4(0.0f, 0.5f, 0.5f, 1.0f), // regular pattern 2
float4(0.5f, 0.0f, 1.0f, 1.0f), // regular pattern 3
float4(1.0f, 0.5f, 1.0f, 1.0f), // regular pattern 4
float4(1.0f, 0.5f, 0.5f, 1.0f), // single crease
float4(1.0f, 0.70f, 0.6f, 1.0f), // single crease pattern 0
float4(1.0f, 0.65f, 0.6f, 1.0f), // single crease pattern 1
float4(1.0f, 0.60f, 0.6f, 1.0f), // single crease pattern 2
float4(1.0f, 0.55f, 0.6f, 1.0f), // single crease pattern 3
float4(1.0f, 0.50f, 0.6f, 1.0f), // single crease pattern 4
float4(0.8f, 0.0f, 0.0f, 1.0f), // boundary
float4(0.0f, 0.0f, 0.75f, 1.0f), // boundary pattern 0
float4(0.0f, 0.2f, 0.75f, 1.0f), // boundary pattern 1
float4(0.0f, 0.4f, 0.75f, 1.0f), // boundary pattern 2
float4(0.0f, 0.6f, 0.75f, 1.0f), // boundary pattern 3
float4(0.0f, 0.8f, 0.75f, 1.0f), // boundary pattern 4
float4(0.0f, 1.0f, 0.0f, 1.0f), // corner
float4(0.25f, 0.25f, 0.25f, 1.0f), // corner pattern 0
float4(0.25f, 0.25f, 0.25f, 1.0f), // corner pattern 1
float4(0.25f, 0.25f, 0.25f, 1.0f), // corner pattern 2
float4(0.25f, 0.25f, 0.25f, 1.0f), // corner pattern 3
float4(0.25f, 0.25f, 0.25f, 1.0f), // corner pattern 4
float4(1.0f, 1.0f, 0.0f, 1.0f), // gregory
float4(1.0f, 1.0f, 0.0f, 1.0f), // gregory
float4(1.0f, 1.0f, 0.0f, 1.0f), // gregory
float4(1.0f, 1.0f, 0.0f, 1.0f), // gregory
float4(1.0f, 1.0f, 0.0f, 1.0f), // gregory
float4(1.0f, 1.0f, 0.0f, 1.0f), // gregory
float4(1.0f, 0.5f, 0.0f, 1.0f), // gregory boundary
float4(1.0f, 0.5f, 0.0f, 1.0f), // gregory boundary
float4(1.0f, 0.5f, 0.0f, 1.0f), // gregory boundary
float4(1.0f, 0.5f, 0.0f, 1.0f), // gregory boundary
float4(1.0f, 0.5f, 0.0f, 1.0f), // gregory boundary
float4(1.0f, 0.5f, 0.0f, 1.0f), // gregory boundary
float4(1.0f, 0.7f, 0.3f, 1.0f), // gregory basis
float4(1.0f, 0.7f, 0.3f, 1.0f), // gregory basis
float4(1.0f, 0.7f, 0.3f, 1.0f), // gregory basis
float4(1.0f, 0.7f, 0.3f, 1.0f), // gregory basis
float4(1.0f, 0.7f, 0.3f, 1.0f), // gregory basis
float4(1.0f, 0.7f, 0.3f, 1.0f) // gregory basis
};
int patchType = 0;
#if defined OSD_PATCH_GREGORY
patchType = 4;
#elif defined OSD_PATCH_GREGORY_BOUNDARY
patchType = 5;
#elif defined OSD_PATCH_GREGORY_BASIS
patchType = 6;
#endif
int edgeCount = countbits(OsdGetPatchBoundaryMask(patchParam));
if (edgeCount == 1) {
patchType = 2; // BOUNDARY
}
if (edgeCount == 2) {
patchType = 3; // CORNER
}
int pattern = countbits(OsdGetPatchTransitionMask(patchParam));
#ifdef OSD_PATCH_ENABLE_SINGLE_CREASE
if (sharpness > 0) pattern += 6;
#endif
return patchColors[6*patchType + pattern];
}
// ---------------------------------------------------------------------------
// Pixel Shader
// ---------------------------------------------------------------------------
void
ps_main( in OutputVertex input,
uint primitiveID : SV_PrimitiveID,
bool isFrontFacing : SV_IsFrontFace,
out float4 colorOut : SV_Target )
{
float sharpness = 0;
#ifdef OSD_PATCH_ENABLE_SINGLE_CREASE
sharpness = input.sharpness;
#endif
float4 color = getAdaptivePatchColor(
OsdGetPatchParam(OsdGetPatchIndex(primitiveID)), sharpness);
float3 N = (isFrontFacing ? input.normal : -input.normal);
colorOut = edgeColor(lighting(input.position.xyz, N), input.edgeDistance);
colorOut = edgeColor(lighting(color, input.position.xyz, N), input.edgeDistance);
}
void

View File

@ -43,7 +43,6 @@ GLFWwindow* g_window = 0;
GLFWmonitor* g_primary = 0;
#include <osd/glDrawContext.h>
#include <osd/glDrawRegistry.h>
#include <far/error.h>
#include <osd/cpuEvaluator.h>
@ -56,7 +55,9 @@ OpenSubdiv::Osd::GLMeshInterface *g_mesh = NULL;
#include "../common/stopwatch.h"
#include "../common/simple_math.h"
#include "../common/gl_hud.h"
#include "../common/glShaderCache.h"
#include <osd/glslPatchShaderSource.h>
static const char *shaderSource =
#if defined(GL_ARB_tessellation_shader) || defined(GL_VERSION_4_0)
#include "shader.gen.h"
@ -529,6 +530,14 @@ union Effect {
}
};
static Effect
GetEffect(bool uvDraw = false) {
return Effect(g_displayStyle, uvDraw);
}
// ---------------------------------------------------------------------------
struct EffectDesc {
EffectDesc(OpenSubdiv::Far::PatchDescriptor desc,
Effect effect) : desc(desc), effect(effect),
@ -546,199 +555,147 @@ struct EffectDesc {
}
};
class EffectDrawRegistry : public OpenSubdiv::Osd::GLDrawRegistry<EffectDesc> {
// ---------------------------------------------------------------------------
protected:
virtual ConfigType *
_CreateDrawConfig(EffectDesc const & desc, SourceConfigType const * sconfig);
class ShaderCache : public GLShaderCache<EffectDesc> {
public:
virtual GLDrawConfig *CreateDrawConfig(EffectDesc const &effectDesc) {
virtual SourceConfigType *
_CreateDrawSourceConfig(EffectDesc const & desc);
};
EffectDrawRegistry::SourceConfigType *
EffectDrawRegistry::_CreateDrawSourceConfig(EffectDesc const & effectDesc) {
Effect effect = effectDesc.effect;
SourceConfigType * sconfig =
BaseRegistry::_CreateDrawSourceConfig(effectDesc.desc);
assert(sconfig);
using namespace OpenSubdiv;
// compile shader program
#if defined(GL_ARB_tessellation_shader) || defined(GL_VERSION_4_0)
const char *glslVersion = "#version 400\n";
const char *glslVersion = "#version 400\n";
#else
const char *glslVersion = "#version 330\n";
const char *glslVersion = "#version 330\n";
#endif
GLDrawConfig *config = new GLDrawConfig(glslVersion);
typedef OpenSubdiv::Far::PatchDescriptor Descriptor;
Far::PatchDescriptor::Type type = effectDesc.desc.GetType();
// legacy gregory patch requires OSD_MAX_VALENCE and OSD_NUM_ELEMENTS defined
if (effectDesc.desc.GetType() == Descriptor::GREGORY or
effectDesc.desc.GetType() == Descriptor::GREGORY_BOUNDARY) {
std::ostringstream ss;
ss << effectDesc.maxValence;
sconfig->commonShader.AddDefine("OSD_MAX_VALENCE", ss.str());
// common defines
std::stringstream ss;
if (type == Far::PatchDescriptor::QUADS) {
ss << "#define PRIM_QUAD\n";
} else {
ss << "#define PRIM_TRI\n";
}
if (effectDesc.effect.uvDraw) {
ss << "#define GEOMETRY_OUT_FILL\n";
ss << "#define GEOMETRY_UV_VIEW\n";
} else {
switch (effectDesc.effect.displayStyle) {
case kWire:
ss << "#define GEOMETRY_OUT_WIRE\n";
break;
case kWireShaded:
ss << "#define GEOMETRY_OUT_LINE\n";
break;
case kShaded:
ss << "#define GEOMETRY_OUT_FILL\n";
break;
}
}
// for legacy gregory
ss << "#define OSD_MAX_VALENCE " << effectDesc.maxValence << "\n";
ss << "#define OSD_NUM_ELEMENTS " << effectDesc.numElements << "\n";
// face varying width
ss << "#define OSD_FVAR_WIDTH 2\n";
// include osd PatchCommon
ss << Osd::GLSLPatchShaderSource::GetCommonShaderSource();
std::string common = ss.str();
ss.str("");
ss << effectDesc.numElements;
sconfig->commonShader.AddDefine("OSD_NUM_ELEMENTS", ss.str());
}
// vertex shader
ss << common
// enable local vertex shader
<< (effectDesc.desc.IsAdaptive() ? "" : "#define VERTEX_SHADER\n")
<< shaderSource
<< Osd::GLSLPatchShaderSource::GetVertexShaderSource(type);
config->CompileAndAttachShader(GL_VERTEX_SHADER, ss.str());
ss.str("");
if (effectDesc.desc.GetType() == Descriptor::QUADS or
effectDesc.desc.GetType() == Descriptor::TRIANGLES) {
sconfig->vertexShader.source = shaderSource;
sconfig->vertexShader.version = glslVersion;
sconfig->vertexShader.AddDefine("VERTEX_SHADER");
} else {
sconfig->geometryShader.AddDefine("SMOOTH_NORMALS");
}
if (effectDesc.desc.IsAdaptive()) {
// tess control shader
ss << common
<< shaderSource
<< Osd::GLSLPatchShaderSource::GetTessControlShaderSource(type);
config->CompileAndAttachShader(GL_TESS_CONTROL_SHADER, ss.str());
ss.str("");
sconfig->geometryShader.source = shaderSource;
sconfig->geometryShader.version = glslVersion;
sconfig->geometryShader.AddDefine("GEOMETRY_SHADER");
sconfig->fragmentShader.source = shaderSource;
sconfig->fragmentShader.version = glslVersion;
sconfig->fragmentShader.AddDefine("FRAGMENT_SHADER");
sconfig->commonShader.AddDefine("OSD_FVAR_WIDTH", "2");
if (effectDesc.desc.GetType() == Descriptor::QUADS) {
// uniform catmark, bilinear
sconfig->geometryShader.AddDefine("PRIM_QUAD");
sconfig->fragmentShader.AddDefine("PRIM_QUAD");
sconfig->commonShader.AddDefine("UNIFORM_SUBDIVISION");
} else if (effectDesc.desc.GetType() == Descriptor::TRIANGLES) {
// uniform loop
sconfig->geometryShader.AddDefine("PRIM_TRI");
sconfig->fragmentShader.AddDefine("PRIM_TRI");
sconfig->commonShader.AddDefine("LOOP");
sconfig->commonShader.AddDefine("UNIFORM_SUBDIVISION");
} else {
// adaptive
sconfig->vertexShader.source = shaderSource + sconfig->vertexShader.source;
sconfig->tessControlShader.source = shaderSource + sconfig->tessControlShader.source;
sconfig->tessEvalShader.source = shaderSource + sconfig->tessEvalShader.source;
sconfig->geometryShader.AddDefine("PRIM_TRI");
sconfig->fragmentShader.AddDefine("PRIM_TRI");
}
if (effect.uvDraw) {
sconfig->commonShader.AddDefine("GEOMETRY_OUT_FILL");
sconfig->commonShader.AddDefine("GEOMETRY_UV_VIEW");
} else {
switch (effect.displayStyle) {
case kWire:
sconfig->commonShader.AddDefine("GEOMETRY_OUT_WIRE");
break;
case kWireShaded:
sconfig->commonShader.AddDefine("GEOMETRY_OUT_LINE");
break;
case kShaded:
sconfig->commonShader.AddDefine("GEOMETRY_OUT_FILL");
break;
// tess eval shader
ss << common
<< shaderSource
<< Osd::GLSLPatchShaderSource::GetTessEvalShaderSource(type);
config->CompileAndAttachShader(GL_TESS_EVALUATION_SHADER, ss.str());
ss.str("");
}
}
return sconfig;
}
// geometry shader
ss << common
<< "#define GEOMETRY_SHADER\n"
<< shaderSource;
config->CompileAndAttachShader(GL_GEOMETRY_SHADER, ss.str());
ss.str("");
EffectDrawRegistry::ConfigType *
EffectDrawRegistry::_CreateDrawConfig(
DescType const & effectDesc,
SourceConfigType const * sconfig) {
// fragment shader
ss << common
<< "#define FRAGMENT_SHADER\n"
<< shaderSource;
config->CompileAndAttachShader(GL_FRAGMENT_SHADER, ss.str());
ss.str("");
ConfigType * config = BaseRegistry::_CreateDrawConfig(effectDesc.desc, sconfig);
assert(config);
if (!config->Link()) {
delete config;
return NULL;
}
GLuint uboIndex;
// assign uniform locations
GLuint uboIndex;
GLuint program = config->GetProgram();
g_transformBinding = 0;
uboIndex = glGetUniformBlockIndex(program, "Transform");
if (uboIndex != GL_INVALID_INDEX)
glUniformBlockBinding(program, uboIndex, g_transformBinding);
// XXXdyu can use layout(binding=) with GLSL 4.20 and beyond
g_transformBinding = 0;
uboIndex = glGetUniformBlockIndex(config->program, "Transform");
if (uboIndex != GL_INVALID_INDEX)
glUniformBlockBinding(config->program, uboIndex, g_transformBinding);
g_tessellationBinding = 1;
uboIndex = glGetUniformBlockIndex(program, "Tessellation");
if (uboIndex != GL_INVALID_INDEX)
glUniformBlockBinding(program, uboIndex, g_tessellationBinding);
g_tessellationBinding = 1;
uboIndex = glGetUniformBlockIndex(config->program, "Tessellation");
if (uboIndex != GL_INVALID_INDEX)
glUniformBlockBinding(config->program, uboIndex, g_tessellationBinding);
// assign texture locations
GLint loc;
glUseProgram(program);
if ((loc = glGetUniformLocation(program, "OsdVertexBuffer")) != -1) {
glUniform1i(loc, 0); // GL_TEXTURE0
}
if ((loc = glGetUniformLocation(program, "OsdValenceBuffer")) != -1) {
glUniform1i(loc, 1); // GL_TEXTURE1
}
if ((loc = glGetUniformLocation(program, "OsdQuadOffsetBuffer")) != -1) {
glUniform1i(loc, 2); // GL_TEXTURE2
}
if ((loc = glGetUniformLocation(program, "OsdPatchParamBuffer")) != -1) {
glUniform1i(loc, 3); // GL_TEXTURE3
}
if ((loc = glGetUniformLocation(program, "OsdFVarDataBuffer")) != -1) {
glUniform1i(loc, 4); // GL_TEXTURE4
}
GLint loc;
#if not defined(GL_ARB_separate_shader_objects) || defined(GL_VERSION_4_1)
glUseProgram(config->program);
if ((loc = glGetUniformLocation(config->program, "OsdVertexBuffer")) != -1) {
glUniform1i(loc, 0); // GL_TEXTURE0
return config;
}
if ((loc = glGetUniformLocation(config->program, "OsdValenceBuffer")) != -1) {
glUniform1i(loc, 1); // GL_TEXTURE1
}
if ((loc = glGetUniformLocation(config->program, "OsdQuadOffsetBuffer")) != -1) {
glUniform1i(loc, 2); // GL_TEXTURE2
}
if ((loc = glGetUniformLocation(config->program, "OsdPatchParamBuffer")) != -1) {
glUniform1i(loc, 3); // GL_TEXTURE3
}
if ((loc = glGetUniformLocation(config->program, "OsdFVarDataBuffer")) != -1) {
glUniform1i(loc, 4); // GL_TEXTURE4
}
#else
if ((loc = glGetUniformLocation(config->program, "OsdVertexBuffer")) != -1) {
glProgramUniform1i(config->program, loc, 0); // GL_TEXTURE0
}
if ((loc = glGetUniformLocation(config->program, "OsdValenceBuffer")) != -1) {
glProgramUniform1i(config->program, loc, 1); // GL_TEXTURE1
}
if ((loc = glGetUniformLocation(config->program, "OsdQuadOffsetBuffer")) != -1) {
glProgramUniform1i(config->program, loc, 2); // GL_TEXTURE2
}
if ((loc = glGetUniformLocation(config->program, "OsdPatchParamBuffer")) != -1) {
glProgramUniform1i(config->program, loc, 3); // GL_TEXTURE3
}
if ((loc = glGetUniformLocation(config->program, "OsdFVarDataBuffer")) != -1) {
glProgramUniform1i(config->program, loc, 4); // GL_TEXTURE4
}
#endif
};
return config;
}
EffectDrawRegistry effectRegistry;
static Effect
GetEffect(bool uvDraw = false) {
return Effect(g_displayStyle, uvDraw);
}
ShaderCache g_shaderCache;
//------------------------------------------------------------------------------
static GLuint
bindProgram(Effect effect, OpenSubdiv::Osd::DrawContext::PatchArray const & patch) {
EffectDesc effectDesc(patch.GetDescriptor(), effect);
// only legacy gregory needs maxValence and numElements
int maxValence = g_mesh->GetDrawContext()->GetMaxValence();
int numElements = 3;
typedef OpenSubdiv::Far::PatchDescriptor Descriptor;
if (patch.GetDescriptor().GetType() == Descriptor::GREGORY or
patch.GetDescriptor().GetType() == Descriptor::GREGORY_BOUNDARY) {
effectDesc.maxValence = maxValence;
effectDesc.numElements = numElements;
}
EffectDrawRegistry::ConfigType *
config = effectRegistry.GetDrawConfig(effectDesc);
GLuint program = config->program;
glUseProgram(program);
static void
updateUniformBlocks() {
if (!g_transformUB) {
glGenBuffers(1, &g_transformUB);
glBindBuffer(GL_UNIFORM_BUFFER, g_transformUB);
@ -771,7 +728,10 @@ bindProgram(Effect effect, OpenSubdiv::Osd::DrawContext::PatchArray const & patc
glBindBuffer(GL_UNIFORM_BUFFER, 0);
glBindBufferBase(GL_UNIFORM_BUFFER, g_tessellationBinding, g_tessellationUB);
}
static void
bindTextures() {
if (g_mesh->GetDrawContext()->GetVertexTextureBuffer()) {
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_BUFFER,
@ -799,8 +759,62 @@ bindProgram(Effect effect, OpenSubdiv::Osd::DrawContext::PatchArray const & patc
}
glActiveTexture(GL_TEXTURE0);
}
return program;
static GLenum
bindProgram(Effect effect, OpenSubdiv::Osd::DrawContext::PatchArray const & patch) {
EffectDesc effectDesc(patch.GetDescriptor(), effect);
typedef OpenSubdiv::Far::PatchDescriptor Descriptor;
if (patch.GetDescriptor().GetType() == Descriptor::GREGORY or
patch.GetDescriptor().GetType() == Descriptor::GREGORY_BOUNDARY) {
// only legacy gregory needs maxValence and numElements
int maxValence = g_mesh->GetDrawContext()->GetMaxValence();
int numElements = 3;
effectDesc.maxValence = maxValence;
effectDesc.numElements = numElements;
}
// lookup shader cache (compile the shader if needed)
GLDrawConfig *config = g_shaderCache.GetDrawConfig(effectDesc);
if (!config) return 0;
GLuint program = config->GetProgram();
glUseProgram(program);
// bind standalone uniforms
GLint uniformGregoryQuadOffsetBase =
glGetUniformLocation(program, "GregoryQuadOffsetBase");
GLint uniformPrimitiveIdBase =
glGetUniformLocation(program, "PrimitiveIdBase");
if (uniformGregoryQuadOffsetBase >= 0)
glUniform1i(uniformGregoryQuadOffsetBase, patch.GetQuadOffsetIndex());
if (uniformPrimitiveIdBase >=0)
glUniform1i(uniformPrimitiveIdBase, patch.GetPatchIndex());
// return primtype
GLenum primType;
switch(effectDesc.desc.GetType()) {
case Descriptor::QUADS:
primType = GL_LINES_ADJACENCY;
break;
case Descriptor::TRIANGLES:
primType = GL_TRIANGLES;
break;
default:
#if defined(GL_ARB_tessellation_shader) || defined(GL_VERSION_4_0)
primType = GL_PATCHES;
glPatchParameteri(GL_PATCH_VERTICES, effectDesc.desc.GetNumControlVertices());
#else
primType = GL_POINTS;
#endif
break;
}
return primType;
}
//------------------------------------------------------------------------------
@ -849,50 +863,15 @@ display() {
if (g_displayStyle == kWire)
glDisable(GL_CULL_FACE);
updateUniformBlocks();
bindTextures();
// patch drawing
for (int i = 0; i < (int)patches.size(); ++i) {
OpenSubdiv::Osd::DrawContext::PatchArray const & patch = patches[i];
OpenSubdiv::Far::PatchDescriptor desc = patch.GetDescriptor();
OpenSubdiv::Far::PatchDescriptor::Type patchType = desc.GetType();
GLenum primType = bindProgram(GetEffect(), patch);
GLenum primType;
switch (patchType) {
case OpenSubdiv::Far::PatchDescriptor::QUADS:
primType = GL_LINES_ADJACENCY;
break;
case OpenSubdiv::Far::PatchDescriptor::TRIANGLES:
primType = GL_TRIANGLES;
break;
default:
#if defined(GL_ARB_tessellation_shader) || defined(GL_VERSION_4_0)
primType = GL_PATCHES;
glPatchParameteri(GL_PATCH_VERTICES, desc.GetNumControlVertices());
#else
primType = GL_POINTS;
#endif
}
#if defined(GL_ARB_tessellation_shader) || defined(GL_VERSION_4_0)
GLuint program = bindProgram(GetEffect(), patch);
GLuint uniformGregoryQuadOffsetBase =
glGetUniformLocation(program, "GregoryQuadOffsetBase");
GLuint uniformPrimitiveIdBase =
glGetUniformLocation(program, "PrimitiveIdBase");
glProgramUniform1i(program, uniformGregoryQuadOffsetBase,
patch.GetQuadOffsetIndex());
glProgramUniform1i(program, uniformPrimitiveIdBase,
patch.GetPatchIndex());
#else
GLuint program = bindProgram(GetEffect(), patch);
GLint uniformPrimitiveIdBase =
glGetUniformLocation(program, "PrimitiveIdBase");
if (uniformPrimitiveIdBase != -1)
glUniform1i(uniformPrimitiveIdBase, patch.GetPatchIndex());
#endif
glDrawElements(primType, patch.GetNumIndices(), GL_UNSIGNED_INT,
(void *)(patch.GetVertIndex() * sizeof(unsigned int)));
}
@ -905,8 +884,6 @@ display() {
drawCageEdges();
drawCageVertices();
g_hud.GetFrameBuffer()->ApplyImageShader();
// ---------------------------------------------
// uv viewport
glViewport(g_width/2, 0, g_width/2, g_height);
@ -920,46 +897,8 @@ display() {
for (int i = 0; i < (int)patches.size(); ++i) {
OpenSubdiv::Osd::DrawContext::PatchArray const & patch = patches[i];
OpenSubdiv::Far::PatchDescriptor desc = patch.GetDescriptor();
OpenSubdiv::Far::PatchDescriptor::Type patchType = desc.GetType();
GLenum primType = bindProgram(GetEffect(/*uvDraw=*/ true), patch);
GLenum primType;
switch (patchType) {
case OpenSubdiv::Far::PatchDescriptor::QUADS:
primType = GL_LINES_ADJACENCY;
break;
case OpenSubdiv::Far::PatchDescriptor::TRIANGLES:
primType = GL_TRIANGLES;
break;
default:
#if defined(GL_ARB_tessellation_shader) || defined(GL_VERSION_4_0)
primType = GL_PATCHES;
glPatchParameteri(GL_PATCH_VERTICES, desc.GetNumControlVertices());
#else
primType = GL_POINTS;
#endif
}
#if defined(GL_ARB_tessellation_shader) || defined(GL_VERSION_4_0)
GLuint program = bindProgram(GetEffect(/*uvDraw=*/ true), patch);
GLuint uniformGregoryQuadOffsetBase =
glGetUniformLocation(program, "GregoryQuadOffsetBase");
GLuint uniformPrimitiveIdBase =
glGetUniformLocation(program, "PrimitiveIdBase");
glProgramUniform1i(program, uniformGregoryQuadOffsetBase,
patch.GetQuadOffsetIndex());
glProgramUniform1i(program, uniformPrimitiveIdBase,
patch.GetPatchIndex());
#else
GLuint program = bindProgram(GetEffect(/*uvDraw=*/ true), patch);
GLint uniformPrimitiveIdBase =
glGetUniformLocation(program, "PrimitiveIdBase");
if (uniformPrimitiveIdBase != -1)
glUniform1i(uniformPrimitiveIdBase, patch.GetPatchIndex());
#endif
glDrawElements(primType, patch.GetNumIndices(), GL_UNSIGNED_INT,
(void *)(patch.GetVertIndex() * sizeof(unsigned int)));
}
@ -969,6 +908,8 @@ display() {
// full viewport
glViewport(0, 0, g_width, g_height);
g_hud.GetFrameBuffer()->ApplyImageShader();
if (g_hud.IsVisible()) {
g_hud.DrawString(10, -40, "Tess level : %d", g_tessLevel);
g_hud.Flush();

View File

@ -83,16 +83,17 @@
#endif
#include <osd/glDrawContext.h>
#include <osd/glDrawRegistry.h>
#include <osd/glMesh.h>
#include <common/vtr_utils.h>
#include "../common/patchColors.h"
#include "../common/stb_image_write.h" // common.obj has an implementation.
#include "../common/glShaderCache.h"
#include "init_shapes.h"
using namespace OpenSubdiv;
#include <osd/glslPatchShaderSource.h>
static const char *shaderSource =
#include "shader.gen.h"
;
@ -119,105 +120,107 @@ setGLCoreProfile() {
glfwOpenWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
}
// ---------------------------------------------------------------------------
class DrawRegistry : public Osd::GLDrawRegistry<> {
class ShaderCache : public GLShaderCache<OpenSubdiv::Far::PatchDescriptor> {
public:
DrawRegistry(std::string const &displayMode)
: _displayMode(displayMode) { }
ShaderCache(std::string const &displayMode) : _displayMode(displayMode) { }
protected:
virtual SourceConfigType *
_CreateDrawSourceConfig(DescType const & desc);
virtual GLDrawConfig *CreateDrawConfig(OpenSubdiv::Far::PatchDescriptor const &desc) {
virtual ConfigType *
_CreateDrawConfig(DescType const & desc,
SourceConfigType const * sconfig);
using namespace OpenSubdiv;
// compile shader program
#if defined(GL_ARB_tessellation_shader) || defined(GL_VERSION_4_0)
const char *glslVersion = "#version 400\n";
#else
const char *glslVersion = "#version 330\n";
#endif
GLDrawConfig *config = new GLDrawConfig(glslVersion);
Far::PatchDescriptor::Type type = desc.GetType();
// common defines
std::stringstream ss;
if (type == Far::PatchDescriptor::QUADS) {
ss << "#define PRIM_QUAD\n";
} else {
ss << "#define PRIM_TRI\n";
}
if (desc.IsAdaptive()) {
ss << "#define SMOOTH_NORMALS\n";
}
ss << "#define DISPLAY_MODE_" << _displayMode << "\n";
ss << "#define OSD_ENABLE_PATCH_CULL\n";
ss << "#define GEOMETRY_OUT_LINE\n";
// include osd PatchCommon
ss << Osd::GLSLPatchShaderSource::GetCommonShaderSource();
std::string common = ss.str();
ss.str("");
// vertex shader
ss << common
<< (desc.IsAdaptive() ? "" : "#define VERTEX_SHADER\n") // for my shader source
<< shaderSource
<< Osd::GLSLPatchShaderSource::GetVertexShaderSource(type);
config->CompileAndAttachShader(GL_VERTEX_SHADER, ss.str());
ss.str("");
if (desc.IsAdaptive()) {
// tess control shader
ss << common
<< shaderSource
<< Osd::GLSLPatchShaderSource::GetTessControlShaderSource(type);
config->CompileAndAttachShader(GL_TESS_CONTROL_SHADER, ss.str());
ss.str("");
// tess eval shader
ss << common
<< shaderSource
<< Osd::GLSLPatchShaderSource::GetTessEvalShaderSource(type);
config->CompileAndAttachShader(GL_TESS_EVALUATION_SHADER, ss.str());
ss.str("");
}
// geometry shader
ss << common
<< "#define GEOMETRY_SHADER\n" // for my shader source
<< shaderSource;
config->CompileAndAttachShader(GL_GEOMETRY_SHADER, ss.str());
ss.str("");
// fragment shader
ss << common
<< "#define FRAGMENT_SHADER\n" // for my shader source
<< shaderSource;
config->CompileAndAttachShader(GL_FRAGMENT_SHADER, ss.str());
ss.str("");
if (!config->Link()) {
delete config;
return NULL;
}
// assign uniform locations
GLuint uboIndex;
GLuint program = config->GetProgram();
uboIndex = glGetUniformBlockIndex(program, "Transform");
if (uboIndex != GL_INVALID_INDEX)
glUniformBlockBinding(program, uboIndex, 0);
// assign texture locations
GLint loc;
if ((loc = glGetUniformLocation(program, "OsdPatchParamBuffer")) != -1) {
glProgramUniform1i(program, loc, 0); // GL_TEXTURE0
}
return config;
}
private:
std::string _displayMode;
};
DrawRegistry::ConfigType *
DrawRegistry::_CreateDrawConfig(DescType const & desc,
SourceConfigType const * sconfig) {
ConfigType * config = BaseRegistry::_CreateDrawConfig(desc, sconfig);
assert(config);
GLuint uboIndex = glGetUniformBlockIndex(config->program, "Transform");
glUniformBlockBinding(config->program, uboIndex, 0);
GLint loc = glGetUniformLocation(config->program, "OsdPatchParamBuffer");
if (loc != -1) {
glUniform1i(loc, 0); // GL_TEXTURE0
}
return config;
};
DrawRegistry::SourceConfigType *
DrawRegistry::_CreateDrawSourceConfig(DescType const & desc) {
typedef Far::PatchDescriptor Descriptor;
SourceConfigType * sconfig =
BaseRegistry::_CreateDrawSourceConfig(desc);
assert(sconfig);
const char *glslVersion = "#version 410\n";
if (desc.GetType() == Descriptor::QUADS or
desc.GetType() == Descriptor::TRIANGLES) {
sconfig->vertexShader.source = shaderSource;
sconfig->vertexShader.version = glslVersion;
sconfig->vertexShader.AddDefine("VERTEX_SHADER");
} else {
sconfig->geometryShader.AddDefine("SMOOTH_NORMALS");
}
sconfig->geometryShader.source = shaderSource;
sconfig->geometryShader.version = glslVersion;
sconfig->geometryShader.AddDefine("GEOMETRY_SHADER");
sconfig->fragmentShader.source = shaderSource;
sconfig->fragmentShader.version = glslVersion;
sconfig->fragmentShader.AddDefine("FRAGMENT_SHADER");
if (desc.GetType() == Descriptor::QUADS) {
// uniform catmark, bilinear
sconfig->geometryShader.AddDefine("PRIM_QUAD");
sconfig->fragmentShader.AddDefine("PRIM_QUAD");
sconfig->commonShader.AddDefine("UNIFORM_SUBDIVISION");
} else if (desc.GetType() == Descriptor::TRIANGLES) {
// uniform loop
sconfig->geometryShader.AddDefine("PRIM_TRI");
sconfig->fragmentShader.AddDefine("PRIM_TRI");
sconfig->commonShader.AddDefine("LOOP");
sconfig->commonShader.AddDefine("UNIFORM_SUBDIVISION");
} else {
// adaptive
sconfig->vertexShader.source =
shaderSource + sconfig->vertexShader.source;
sconfig->tessControlShader.source =
shaderSource + sconfig->tessControlShader.source;
sconfig->tessEvalShader.source =
shaderSource + sconfig->tessEvalShader.source;
sconfig->geometryShader.AddDefine("PRIM_TRI");
sconfig->fragmentShader.AddDefine("PRIM_TRI");
}
sconfig->commonShader.AddDefine("DISPLAY_MODE_" + _displayMode);
// sconfig->commonShader.AddDefine("OSD_ENABLE_SCREENSPACE_TESSELLATION");
// sconfig->commonShader.AddDefine("OSD_FRACTIONAL_ODD_SPACING");
sconfig->commonShader.AddDefine("OSD_ENABLE_PATCH_CULL");
sconfig->commonShader.AddDefine("GEOMETRY_OUT_LINE");
return sconfig;
}
// ---------------------------------------------------------------------------
static Osd::GLMeshInterface *
@ -314,7 +317,7 @@ createOsdMesh(std::string const &kernel,
void runTest(ShapeDesc const &shapeDesc, std::string const &kernel,
int level, bool adaptive,
DrawRegistry *drawRegistry) {
ShaderCache *shaderCache) {
std::cout << "Testing " << shapeDesc.name << ", kernel = " << kernel << "\n";
@ -441,7 +444,7 @@ void runTest(ShapeDesc const &shapeDesc, std::string const &kernel,
glPatchParameteri(GL_PATCH_VERTICES, desc.GetNumControlVertices());
}
GLuint program = drawRegistry->GetDrawConfig(desc)->program;
GLuint program = shaderCache->GetDrawConfig(desc)->GetProgram();
glUseProgram(program);
GLuint diffuseColor =
@ -628,7 +631,7 @@ int main(int argc, char ** argv) {
glBindBufferBase(GL_UNIFORM_BUFFER, /*binding=*/0, transformUB);
// create draw registry;
DrawRegistry drawRegistry(displayMode);
ShaderCache shaderCache(displayMode);
// write report html
if (writeToFile) {
@ -705,7 +708,7 @@ int main(int argc, char ** argv) {
#endif
for (size_t i = 0; i < g_shapes.size(); ++i) {
// run test
runTest(g_shapes[i], kernel, isolationLevel, adaptive, &drawRegistry);
runTest(g_shapes[i], kernel, isolationLevel, adaptive, &shaderCache);
if (writeToFile) {
// read back pixels

View File

@ -43,7 +43,6 @@ GLFWwindow* g_window=0;
GLFWmonitor* g_primary=0;
#include <osd/glDrawContext.h>
#include <osd/glDrawRegistry.h>
#include <far/error.h>
#include <far/ptexIndices.h>
@ -57,9 +56,11 @@ OpenSubdiv::Osd::GLMeshInterface *g_mesh;
#include "../common/stopwatch.h"
#include "../common/simple_math.h"
#include "../common/gl_hud.h"
#include "../common/glShaderCache.h"
#include "init_shapes.h"
#include <osd/glslPatchShaderSource.h>
static const char *shaderSource =
#include "shader.gen.h"
;
@ -357,223 +358,155 @@ struct EffectDesc {
}
};
class EffectDrawRegistry : public OpenSubdiv::Osd::GLDrawRegistry<EffectDesc> {
// ---------------------------------------------------------------------------
protected:
virtual ConfigType *
_CreateDrawConfig(EffectDesc const & desc, SourceConfigType const * sconfig);
class ShaderCache : public GLShaderCache<EffectDesc> {
public:
virtual GLDrawConfig *CreateDrawConfig(EffectDesc const &effectDesc) {
virtual SourceConfigType *
_CreateDrawSourceConfig(EffectDesc const & desc);
};
using namespace OpenSubdiv;
EffectDrawRegistry::SourceConfigType *
EffectDrawRegistry::_CreateDrawSourceConfig(EffectDesc const & effectDesc) {
// compile shader program
const char *glslVersion = "#version 420\n";
GLDrawConfig *config = new GLDrawConfig(glslVersion);
typedef OpenSubdiv::Far::PatchDescriptor Descriptor;
Far::PatchDescriptor::Type type = effectDesc.desc.GetType();
Effect effect = effectDesc.effect;
std::stringstream ss;
if (effectDesc.effect.color) {
ss << "#define USE_PTEX_COLOR\n";
}
if (effectDesc.effect.displacement) {
ss << "#define USE_PTEX_DISPLACEMENT\n";
}
ss << "#define OSD_ENABLE_SCREENSPACE_TESSELLATION\n";
if (effectDesc.effect.wire == 0) {
ss << "#define GEOMETRY_OUT_WIRE\n";
} else if (effectDesc.effect.wire == 1) {
ss << "#define GEOMETRY_OUT_FILL\n";
} else {
ss << "#define GEOMETRY_OUT_LINE\n";
}
SourceConfigType * sconfig =
BaseRegistry::_CreateDrawSourceConfig(effectDesc.desc);
// for legacy gregory
ss << "#define OSD_MAX_VALENCE " << effectDesc.maxValence << "\n";
ss << "#define OSD_NUM_ELEMENTS " << effectDesc.numElements << "\n";
// legacy gregory patch requires OSD_MAX_VALENCE and OSD_NUM_ELEMENTS defined
if (effectDesc.desc.GetType() == Descriptor::GREGORY or
effectDesc.desc.GetType() == Descriptor::GREGORY_BOUNDARY) {
std::ostringstream ss;
ss << effectDesc.maxValence;
sconfig->commonShader.AddDefine("OSD_MAX_VALENCE", ss.str());
// include osd PatchCommon
ss << Osd::GLSLPatchShaderSource::GetCommonShaderSource();
std::string common = ss.str();
ss.str("");
ss << effectDesc.numElements;
sconfig->commonShader.AddDefine("OSD_NUM_ELEMENTS", ss.str());
// vertex shader
ss << common
<< (effectDesc.desc.IsAdaptive() ? "" : "#define VERTEX_SHADER\n")
<< (effectDesc.effect.paint ? paintShaderSource : shaderSource)
<< Osd::GLSLPatchShaderSource::GetVertexShaderSource(type);
config->CompileAndAttachShader(GL_VERTEX_SHADER, ss.str());
ss.str("");
if (effectDesc.desc.IsAdaptive()) {
// tess control shader
ss << common
<< (effectDesc.effect.paint ? paintShaderSource : shaderSource)
<< Osd::GLSLPatchShaderSource::GetTessControlShaderSource(type);
config->CompileAndAttachShader(GL_TESS_CONTROL_SHADER, ss.str());
ss.str("");
// tess eval shader
ss << common
<< (effectDesc.effect.paint ? paintShaderSource : shaderSource)
<< Osd::GLSLPatchShaderSource::GetTessEvalShaderSource(type);
config->CompileAndAttachShader(GL_TESS_EVALUATION_SHADER, ss.str());
ss.str("");
}
// geometry shader
ss << common
<< "#define GEOMETRY_SHADER\n" // for my shader source
<< (effectDesc.effect.paint ? paintShaderSource : shaderSource);
config->CompileAndAttachShader(GL_GEOMETRY_SHADER, ss.str());
ss.str("");
// fragment shader
ss << common
<< "#define FRAGMENT_SHADER\n" // for my shader source
<< (effectDesc.effect.paint ? paintShaderSource : shaderSource);
config->CompileAndAttachShader(GL_FRAGMENT_SHADER, ss.str());
ss.str("");
if (!config->Link()) {
delete config;
return NULL;
}
// assign uniform locations
GLuint uboIndex;
GLuint program = config->GetProgram();
g_transformBinding = 0;
uboIndex = glGetUniformBlockIndex(program, "Transform");
if (uboIndex != GL_INVALID_INDEX)
glUniformBlockBinding(program, uboIndex, g_transformBinding);
g_tessellationBinding = 1;
uboIndex = glGetUniformBlockIndex(program, "Tessellation");
if (uboIndex != GL_INVALID_INDEX)
glUniformBlockBinding(program, uboIndex, g_tessellationBinding);
g_lightingBinding = 2;
uboIndex = glGetUniformBlockIndex(program, "Lighting");
if (uboIndex != GL_INVALID_INDEX)
glUniformBlockBinding(program, uboIndex, g_lightingBinding);
// assign texture locations
GLint loc;
glUseProgram(program);
if ((loc = glGetUniformLocation(program, "OsdVertexBuffer")) != -1) {
glUniform1i(loc, 0); // GL_TEXTURE0
}
if ((loc = glGetUniformLocation(program, "OsdValenceBuffer")) != -1) {
glUniform1i(loc, 1); // GL_TEXTURE1
}
if ((loc = glGetUniformLocation(program, "OsdQuadOffsetBuffer")) != -1) {
glUniform1i(loc, 2); // GL_TEXTURE2
}
if ((loc = glGetUniformLocation(program, "OsdPatchParamBuffer")) != -1) {
glUniform1i(loc, 3); // GL_TEXTURE3
}
if (effectDesc.effect.paint) {
if ((loc = glGetUniformLocation(program, "outTextureImage")) != -1) {
glUniform1i(loc, 0); // image 0
}
if ((loc = glGetUniformLocation(program, "paintTexture")) != -1) {
glUniform1i(loc, 5); // GL_TEXTURE5
}
if ((loc = glGetUniformLocation(program, "depthTexture")) != -1) {
glUniform1i(loc, 6); // GL_TEXTURE6
}
} else {
if ((loc = glGetUniformLocation(program, "textureImage_Data")) != -1) {
glUniform1i(loc, 5); // GL_TEXTURE5
}
if ((loc = glGetUniformLocation(program, "textureImage_Packing")) != -1) {
glUniform1i(loc, 6); // GL_TEXTURE6
}
if ((loc = glGetUniformLocation(program, "textureImage_Pages")) != -1) {
glUniform1i(loc, 7); // GL_TEXTURE7
}
}
glUseProgram(0);
return config;
}
};
sconfig->commonShader.AddDefine("USE_PTEX_COORD");
if (effect.color) {
sconfig->commonShader.AddDefine("USE_PTEX_COLOR");
}
if (effect.displacement) {
sconfig->commonShader.AddDefine("USE_PTEX_DISPLACEMENT");
}
sconfig->commonShader.AddDefine("OSD_ENABLE_PATCH_CULL");
sconfig->commonShader.AddDefine("OSD_ENABLE_SCREENSPACE_TESSELLATION");
const char *glslVersion = "#version 420\n";
sconfig->vertexShader.source = shaderSource + sconfig->vertexShader.source;
sconfig->tessControlShader.source = shaderSource + sconfig->tessControlShader.source;
sconfig->tessEvalShader.source = shaderSource + sconfig->tessEvalShader.source;
sconfig->vertexShader.version = glslVersion;
sconfig->tessEvalShader.version = glslVersion;
sconfig->tessControlShader.version = glslVersion;
sconfig->geometryShader.version = glslVersion;
sconfig->fragmentShader.version = glslVersion;
if (effect.paint) {
sconfig->geometryShader.source = paintShaderSource;
sconfig->geometryShader.AddDefine("GEOMETRY_SHADER");
sconfig->fragmentShader.source = paintShaderSource;
sconfig->fragmentShader.AddDefine("FRAGMENT_SHADER");
return sconfig;
}
sconfig->geometryShader.AddDefine("SMOOTH_NORMALS");
sconfig->geometryShader.source = shaderSource;
sconfig->geometryShader.AddDefine("GEOMETRY_SHADER");
sconfig->fragmentShader.source = shaderSource;
sconfig->fragmentShader.AddDefine("FRAGMENT_SHADER");
sconfig->geometryShader.AddDefine("PRIM_TRI");
sconfig->fragmentShader.AddDefine("PRIM_TRI");
if (effect.wire == 0) {
sconfig->geometryShader.AddDefine("GEOMETRY_OUT_WIRE");
sconfig->fragmentShader.AddDefine("GEOMETRY_OUT_WIRE");
} else if (effect.wire == 1) {
sconfig->geometryShader.AddDefine("GEOMETRY_OUT_FILL");
sconfig->fragmentShader.AddDefine("GEOMETRY_OUT_FILL");
} else if (effect.wire == 2) {
sconfig->geometryShader.AddDefine("GEOMETRY_OUT_LINE");
sconfig->fragmentShader.AddDefine("GEOMETRY_OUT_LINE");
}
return sconfig;
}
EffectDrawRegistry::ConfigType *
EffectDrawRegistry::_CreateDrawConfig(
DescType const & effectDesc,
SourceConfigType const * sconfig) {
ConfigType * config = BaseRegistry::_CreateDrawConfig(effectDesc.desc, sconfig);
assert(config);
GLuint uboIndex;
// XXXdyu can use layout(binding=) with GLSL 4.20 and beyond
g_transformBinding = 0;
uboIndex = glGetUniformBlockIndex(config->program, "Transform");
if (uboIndex != GL_INVALID_INDEX)
glUniformBlockBinding(config->program, uboIndex, g_transformBinding);
g_tessellationBinding = 1;
uboIndex = glGetUniformBlockIndex(config->program, "Tessellation");
if (uboIndex != GL_INVALID_INDEX)
glUniformBlockBinding(config->program, uboIndex, g_tessellationBinding);
g_lightingBinding = 2;
uboIndex = glGetUniformBlockIndex(config->program, "Lighting");
if (uboIndex != GL_INVALID_INDEX)
glUniformBlockBinding(config->program, uboIndex, g_lightingBinding);
GLint loc;
if ((loc = glGetUniformLocation(config->program, "OsdVertexBuffer")) != -1) {
glProgramUniform1i(config->program, loc, 0); // GL_TEXTURE0
}
if ((loc = glGetUniformLocation(config->program, "OsdValenceBuffer")) != -1) {
glProgramUniform1i(config->program, loc, 1); // GL_TEXTURE1
}
if ((loc = glGetUniformLocation(config->program, "OsdQuadOffsetBuffer")) != -1) {
glProgramUniform1i(config->program, loc, 2); // GL_TEXTURE2
}
if ((loc = glGetUniformLocation(config->program, "OsdPatchParamBuffer")) != -1) {
glProgramUniform1i(config->program, loc, 3); // GL_TEXTURE3
}
return config;
}
EffectDrawRegistry effectRegistry;
//------------------------------------------------------------------------------
static GLuint
bindProgram(Effect effect, OpenSubdiv::Osd::DrawContext::PatchArray const & patch) {
EffectDesc effectDesc(patch.GetDescriptor(), effect);
EffectDrawRegistry::ConfigType *
config = effectRegistry.GetDrawConfig(effectDesc);
GLuint program = config->program;
glUseProgram(program);
if (effect.paint) {
// set image
GLint texImage = glGetUniformLocation(program, "outTextureImage");
glUniform1i(texImage, 0);
glBindImageTexture(0, g_ptexTexels, 0, GL_TRUE, 0, GL_READ_WRITE, GL_R32F);
GLint paintTexture = glGetUniformLocation(program, "paintTexture");
glUniform1i(paintTexture, 0);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, g_paintTexture);
GLint depthTexture = glGetUniformLocation(program, "depthTexture");
glUniform1i(depthTexture, 1);
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, g_depthTexture);
GLint imageSize = glGetUniformLocation(program, "imageSize");
glUniform1i(imageSize, g_pageSize);
glActiveTexture(GL_TEXTURE0);
}
// color ptex
GLint texData = glGetUniformLocation(program, "textureImage_Data");
GLint texPacking = glGetUniformLocation(program, "textureImage_Packing");
GLint texPages = glGetUniformLocation(program, "textureImage_Pages");
glActiveTexture(GL_TEXTURE5);
glBindTexture(GL_TEXTURE_2D_ARRAY, g_ptexTexels);
glProgramUniform1i(program, texData, 5);
glActiveTexture(GL_TEXTURE6);
glBindTexture(GL_TEXTURE_BUFFER, g_ptexLayouts);
glProgramUniform1i(program, texPacking, 6);
glActiveTexture(GL_TEXTURE7);
glBindTexture(GL_TEXTURE_BUFFER, g_ptexPages);
glProgramUniform1i(program, texPages, 7);
glActiveTexture(GL_TEXTURE0);
return program;
}
ShaderCache g_shaderCache;
//------------------------------------------------------------------------------
static void
display() {
g_hud.GetFrameBuffer()->Bind();
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glViewport(0, 0, g_width, g_height);
// primitive counting
glBeginQuery(GL_PRIMITIVES_GENERATED, g_primQuery);
// prepare view matrix
double aspect = g_width/(double)g_height;
identity(g_transformData.ModelViewMatrix);
translate(g_transformData.ModelViewMatrix, -g_pan[0], -g_pan[1], -g_dolly);
rotate(g_transformData.ModelViewMatrix, g_rotate[1], 1, 0, 0);
rotate(g_transformData.ModelViewMatrix, g_rotate[0], 0, 1, 0);
rotate(g_transformData.ModelViewMatrix, -90, 1, 0, 0);
translate(g_transformData.ModelViewMatrix,
-g_center[0], -g_center[1], -g_center[2]);
perspective(g_transformData.ProjectionMatrix,
45.0f, (float)aspect, 0.01f, 500.0f);
multMatrix(g_transformData.ModelViewProjectionMatrix,
g_transformData.ModelViewMatrix,
g_transformData.ProjectionMatrix);
glEnable(GL_DEPTH_TEST);
updateUniformBlocks() {
if (! g_transformUB) {
glGenBuffers(1, &g_transformUB);
glBindBuffer(GL_UNIFORM_BUFFER, g_transformUB);
@ -638,30 +571,137 @@ display() {
glBindBuffer(GL_UNIFORM_BUFFER, 0);
glBindBufferBase(GL_UNIFORM_BUFFER, g_lightingBinding, g_lightingUB);
}
static void bindTextures(Effect effect) {
if (effect.paint) {
// set image
glBindImageTexture(0, g_ptexTexels, 0, GL_TRUE, 0, GL_READ_WRITE, GL_R32F);
glActiveTexture(GL_TEXTURE5);
glBindTexture(GL_TEXTURE_2D, g_paintTexture);
glActiveTexture(GL_TEXTURE6);
glBindTexture(GL_TEXTURE_2D, g_depthTexture);
if (g_mesh->GetDrawContext()->GetVertexTextureBuffer()) {
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_BUFFER,
g_mesh->GetDrawContext()->GetVertexTextureBuffer());
}
if (g_mesh->GetDrawContext()->GetVertexValenceTextureBuffer()) {
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_BUFFER,
g_mesh->GetDrawContext()->GetVertexValenceTextureBuffer());
}
if (g_mesh->GetDrawContext()->GetQuadOffsetsTextureBuffer()) {
glActiveTexture(GL_TEXTURE2);
glBindTexture(GL_TEXTURE_BUFFER,
g_mesh->GetDrawContext()->GetQuadOffsetsTextureBuffer());
}
if (g_mesh->GetDrawContext()->GetPatchParamTextureBuffer()) {
glActiveTexture(GL_TEXTURE3);
glBindTexture(GL_TEXTURE_BUFFER,
g_mesh->GetDrawContext()->GetPatchParamTextureBuffer());
}
} else {
if (g_mesh->GetDrawContext()->GetVertexTextureBuffer()) {
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_BUFFER,
g_mesh->GetDrawContext()->GetVertexTextureBuffer());
}
if (g_mesh->GetDrawContext()->GetVertexValenceTextureBuffer()) {
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_BUFFER,
g_mesh->GetDrawContext()->GetVertexValenceTextureBuffer());
}
if (g_mesh->GetDrawContext()->GetQuadOffsetsTextureBuffer()) {
glActiveTexture(GL_TEXTURE2);
glBindTexture(GL_TEXTURE_BUFFER,
g_mesh->GetDrawContext()->GetQuadOffsetsTextureBuffer());
}
if (g_mesh->GetDrawContext()->GetPatchParamTextureBuffer()) {
glActiveTexture(GL_TEXTURE3);
glBindTexture(GL_TEXTURE_BUFFER,
g_mesh->GetDrawContext()->GetPatchParamTextureBuffer());
}
// color ptex
glActiveTexture(GL_TEXTURE5);
glBindTexture(GL_TEXTURE_2D_ARRAY, g_ptexTexels);
glActiveTexture(GL_TEXTURE6);
glBindTexture(GL_TEXTURE_BUFFER, g_ptexLayouts);
glActiveTexture(GL_TEXTURE7);
glBindTexture(GL_TEXTURE_BUFFER, g_ptexPages);
}
glActiveTexture(GL_TEXTURE0);
}
static GLuint
bindProgram(Effect effect, OpenSubdiv::Osd::DrawContext::PatchArray const & patch) {
EffectDesc effectDesc(patch.GetDescriptor(), effect);
// only legacy gregory needs maxValence and numElements
typedef OpenSubdiv::Far::PatchDescriptor Descriptor;
if (patch.GetDescriptor().GetType() == Descriptor::GREGORY or
patch.GetDescriptor().GetType() == Descriptor::GREGORY_BOUNDARY) {
int maxValence = g_mesh->GetDrawContext()->GetMaxValence();
effectDesc.maxValence = maxValence;
effectDesc.numElements = 3;
}
// lookup shader cache (compile the shader if needed)
GLDrawConfig *config = g_shaderCache.GetDrawConfig(effectDesc);
if (!config) return 0;
GLuint program = config->GetProgram();
glUseProgram(program);
GLint uniformImageSize = glGetUniformLocation(program, "imageSize");
if (uniformImageSize >= 0)
glUniform1i(uniformImageSize, g_pageSize);
GLint uniformGregoryQuadOffsetBase =
glGetUniformLocation(program, "GregoryQuadOffsetBase");
if (uniformGregoryQuadOffsetBase >= 0)
glUniform1i(uniformGregoryQuadOffsetBase, patch.GetQuadOffsetIndex());
GLint uniformPrimitiveIdBase =
glGetUniformLocation(program, "PrimitiveIdBase");
if (uniformPrimitiveIdBase >= 0)
glUniform1i(uniformPrimitiveIdBase, patch.GetPatchIndex());
return program;
}
//------------------------------------------------------------------------------
static void
display() {
g_hud.GetFrameBuffer()->Bind();
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glViewport(0, 0, g_width, g_height);
// primitive counting
glBeginQuery(GL_PRIMITIVES_GENERATED, g_primQuery);
// prepare view matrix
double aspect = g_width/(double)g_height;
identity(g_transformData.ModelViewMatrix);
translate(g_transformData.ModelViewMatrix, -g_pan[0], -g_pan[1], -g_dolly);
rotate(g_transformData.ModelViewMatrix, g_rotate[1], 1, 0, 0);
rotate(g_transformData.ModelViewMatrix, g_rotate[0], 0, 1, 0);
rotate(g_transformData.ModelViewMatrix, -90, 1, 0, 0);
translate(g_transformData.ModelViewMatrix,
-g_center[0], -g_center[1], -g_center[2]);
perspective(g_transformData.ProjectionMatrix,
45.0f, (float)aspect, 0.01f, 500.0f);
multMatrix(g_transformData.ModelViewProjectionMatrix,
g_transformData.ModelViewMatrix,
g_transformData.ProjectionMatrix);
glEnable(GL_DEPTH_TEST);
if (g_wire == 0) {
glDisable(GL_CULL_FACE);
}
updateUniformBlocks();
Effect effect;
effect.color = g_displayColor;
effect.displacement = g_displayDisplacement;
effect.wire = g_wire;
effect.paint = 0;
bindTextures(effect);
// make sure that the vertex buffer is interoped back as a GL resources.
g_mesh->BindVertexBuffer();
@ -679,34 +719,13 @@ display() {
GLenum primType = GL_PATCHES;
glPatchParameteri(GL_PATCH_VERTICES, desc.GetNumControlVertices());
Effect effect;
effect.color = g_displayColor;
effect.displacement = g_displayDisplacement;
effect.wire = g_wire;
effect.paint = 0;
GLuint program = bindProgram(effect, patch);
GLuint diffuseColor = glGetUniformLocation(program, "diffuseColor");
glProgramUniform4f(program, diffuseColor, 1, 1, 1, 1);
GLuint uniformGregoryQuadOffsetBase =
glGetUniformLocation(program, "GregoryQuadOffsetBase");
GLuint uniformPrimitiveIdBase =
glGetUniformLocation(program, "PrimitiveIdBase");
glProgramUniform1i(program, uniformGregoryQuadOffsetBase,
patch.GetQuadOffsetIndex());
glProgramUniform1i(program, uniformPrimitiveIdBase,
patch.GetPatchIndex());
if (g_wire == 0) {
glDisable(GL_CULL_FACE);
}
glDrawElements(primType,
patch.GetNumIndices(), GL_UNSIGNED_INT,
(void *)(patch.GetVertIndex() * sizeof(unsigned int)));
if (g_wire == 0) {
glEnable(GL_CULL_FACE);
}
}
glBindVertexArray(0);
@ -718,6 +737,10 @@ display() {
glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, g_width, g_height);
glBindTexture(GL_TEXTURE_2D, 0);
if (g_wire == 0) {
glEnable(GL_CULL_FACE);
}
GLuint numPrimsGenerated = 0;
glGetQueryObjectuiv(g_primQuery, GL_QUERY_RESULT, &numPrimsGenerated);
@ -809,35 +832,18 @@ drawStroke(int x, int y) {
glBindBufferBase(GL_UNIFORM_BUFFER, g_tessellationBinding, g_tessellationUB);
if (g_mesh->GetDrawContext()->GetVertexTextureBuffer()) {
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_BUFFER,
g_mesh->GetDrawContext()->GetVertexTextureBuffer());
}
if (g_mesh->GetDrawContext()->GetVertexValenceTextureBuffer()) {
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_BUFFER,
g_mesh->GetDrawContext()->GetVertexValenceTextureBuffer());
}
if (g_mesh->GetDrawContext()->GetQuadOffsetsTextureBuffer()) {
glActiveTexture(GL_TEXTURE2);
glBindTexture(GL_TEXTURE_BUFFER,
g_mesh->GetDrawContext()->GetQuadOffsetsTextureBuffer());
}
if (g_mesh->GetDrawContext()->GetPatchParamTextureBuffer()) {
glActiveTexture(GL_TEXTURE3);
glBindTexture(GL_TEXTURE_BUFFER,
g_mesh->GetDrawContext()->GetPatchParamTextureBuffer());
}
glActiveTexture(GL_TEXTURE0);
// make sure that the vertex buffer is interoped back as a GL resources.
g_mesh->BindVertexBuffer();
glBindVertexArray(g_vao);
Effect effect;
effect.color = 0;
effect.displacement = g_displayDisplacement;
effect.wire = 1;
effect.paint = 1;
bindTextures(effect);
OpenSubdiv::Osd::DrawContext::PatchArrayVector const & patches =
g_mesh->GetDrawContext()->GetPatchArrays();
@ -850,21 +856,7 @@ drawStroke(int x, int y) {
GLenum primType = GL_PATCHES;
glPatchParameteri(GL_PATCH_VERTICES, desc.GetNumControlVertices());
Effect effect;
effect.color = 0;
effect.displacement = g_displayDisplacement;
effect.wire = 1;
effect.paint = 1;
GLuint program = bindProgram(effect, patch);
GLuint uniformGregoryQuadOffsetBase =
glGetUniformLocation(program, "GregoryQuadOffsetBase");
GLuint uniformPrimitiveIdBase =
glGetUniformLocation(program, "PrimitiveIdBase");
glProgramUniform1i(program, uniformGregoryQuadOffsetBase,
patch.GetQuadOffsetIndex());
glProgramUniform1i(program, uniformPrimitiveIdBase,
patch.GetPatchIndex());
bindProgram(effect, patch);
glDrawElements(primType,
patch.GetNumIndices(), GL_UNSIGNED_INT,

View File

@ -28,7 +28,6 @@ set(SHADER_FILES
shader.glsl
shader_gl3.glsl
skyshader.glsl
imageshader.glsl
)
list(APPEND PLATFORM_LIBRARIES

File diff suppressed because it is too large Load Diff

View File

@ -1,92 +0,0 @@
//
// Copyright 2013 Pixar
//
// Licensed under the Apache License, Version 2.0 (the "Apache License")
// with the following modification; you may not use this file except in
// compliance with the Apache License and the following modification to it:
// Section 6. Trademarks. is deleted and replaced with:
//
// 6. Trademarks. This License does not grant permission to use the trade
// names, trademarks, service marks, or product names of the Licensor
// and its affiliates, except as required to comply with Section 4(c) of
// the License and to reproduce the content of the NOTICE file.
//
// You may obtain a copy of the Apache License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the Apache License with the above modification is
// distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the Apache License for the specific
// language governing permissions and limitations under the Apache License.
//
//--------------------------------------------------------------
// image vertex shader
//--------------------------------------------------------------
#ifdef IMAGE_VERTEX_SHADER
layout (location=0) in vec2 position;
out vec2 outUV;
void
main()
{
outUV = vec2(position.xy*0.5) + vec2(0.5);
gl_Position = vec4(position.x, position.y, 0, 1);
}
#endif
//--------------------------------------------------------------
// image fragment shader
//--------------------------------------------------------------
#ifdef IMAGE_FRAGMENT_SHADER
uniform sampler2D colorMap;
uniform sampler2D depthMap;
in vec2 outUV;
out vec4 outColor;
#ifdef BLUR
#define NUM_BLUR_SAMPLES 7
uniform vec2 Offsets[NUM_BLUR_SAMPLES];
uniform float Weights[NUM_BLUR_SAMPLES];
void main()
{
outColor = vec4(0);
for (int i = 0; i < NUM_BLUR_SAMPLES; ++i) {
float w = Weights[i];
vec2 o = Offsets[i];
outColor += w * texture(colorMap, outUV + o);
}
}
#endif
#ifdef HIPASS
uniform float Threshold = 0.95;
const vec3 Black = vec3(0, 0, 0);
void main()
{
vec3 c = texture(colorMap, outUV).rgb;
float gray = dot(c, c);
outColor = vec4(gray > Threshold ? c : Black, 1);
}
#endif
#ifdef COMPOSITE
uniform float alpha = 1.0;
void main()
{
//background color as a vertical grey ramp
vec4 fgColor = texture(colorMap, outUV);
vec4 bgColor = vec4(mix(0.1, 0.5, sin(outUV.y*3.14159)));
outColor = mix(bgColor, fgColor, fgColor.a);
}
#endif
#endif

View File

@ -23,11 +23,35 @@
//
//--------------------------------------------------------------
// Common
// Uniforms / Uniform Blocks
//--------------------------------------------------------------
uniform float displacementScale = 1.0;
uniform float mipmapBias = 0;
#define NUM_LIGHTS 2
struct LightSource {
vec4 position;
vec4 ambient;
vec4 diffuse;
vec4 specular;
};
layout(std140) uniform Constant {
mat4 ModelViewMatrix;
mat4 ProjectionMatrix;
mat4 ModelViewProjectionMatrix;
mat4 ModelViewInverseMatrix;
LightSource lightSource[NUM_LIGHTS];
float TessLevel;
float displacementScale;
float mipmapBias;
};
uniform int GregoryQuadOffsetBase;
uniform int PrimitiveIdBase;
//--------------------------------------------------------------
// Common
//--------------------------------------------------------------
vec4 GeneratePatchCoord(vec2 uv, int primitiveID) // for non-adaptive
{
@ -76,24 +100,6 @@ vec4 displacement(vec4 position, vec3 normal, vec4 patchCoord)
}
#endif
//--------------------------------------------------------------
// Uniforms / Uniform Blocks
//--------------------------------------------------------------
layout(std140) uniform Transform {
mat4 ModelViewMatrix;
mat4 ProjectionMatrix;
mat4 ModelViewProjectionMatrix;
mat4 ModelViewInverseMatrix;
};
layout(std140) uniform Tessellation {
float TessLevel;
};
uniform int GregoryQuadOffsetBase;
uniform int PrimitiveIdBase;
//--------------------------------------------------------------
// Osd external functions
//--------------------------------------------------------------
@ -401,25 +407,12 @@ uniform sampler2DArray textureSpecular_Data;
uniform isamplerBuffer textureSpecular_Packing;
#endif
#define NUM_LIGHTS 2
struct LightSource {
vec4 position;
vec4 ambient;
vec4 diffuse;
vec4 specular;
};
layout(std140) uniform Lighting {
LightSource lightSource[NUM_LIGHTS];
};
#if defined COLOR_PATCHTYPE
uniform vec4 overrideColor;
vec4
GetOverrideColor(int patchParam)
GetOverrideColor(ivec3 patchParam)
{
const vec4 patchColors[7*6] = vec4[7*6](
vec4(1.0f, 1.0f, 1.0f, 1.0f), // regular
@ -490,7 +483,7 @@ GetOverrideColor(int patchParam)
patchType = 3; // CORNER
}
int pattern = bitCount(OsdGetPatchTransitionMask(patchParam));
int offset = 7*patchType + pattern;
int offset = 6*patchType + pattern;
return patchColors[offset];
}

View File

@ -22,57 +22,69 @@
// language governing permissions and limitations under the Apache License.
//
layout(std140) uniform Transform {
#define NUM_LIGHTS 2
struct LightSource {
vec4 position;
vec4 ambient;
vec4 diffuse;
vec4 specular;
};
layout(std140) uniform Constant {
mat4 ModelViewMatrix;
mat4 ProjectionMatrix;
mat4 ModelViewProjectionMatrix;
mat4 ModelViewInverseMatrix;
LightSource lightSource[NUM_LIGHTS];
float TessLevel;
float displacementScale;
float mipmapBias;
};
uniform int PrimitiveIdBase;
int OsdPrimitiveIdBase()
{
return PrimitiveIdBase;
}
//--------------------------------------------------------------
// Common
//--------------------------------------------------------------
uniform isamplerBuffer OsdPatchParamBuffer;
uniform int nonAdaptiveLevel;
vec4 PTexLookup(vec4 patchCoord,
sampler2DArray data,
samplerBuffer packings,
isamplerBuffer pages)
{
vec2 uv = patchCoord.xy;
int faceID = int(patchCoord.w);
int page = texelFetch(pages, faceID).x;
vec4 packing = texelFetch(packings, faceID);
vec3 coords = vec3( packing.x + uv.x * packing.z,
packing.y + uv.y * packing.w,
page);
return texture(data, coords);
}
#ifdef USE_PTEX_DISPLACEMENT
#undef OSD_DISPLACEMENT_CALLBACK
#define OSD_DISPLACEMENT_CALLBACK \
outpt.v.position = \
displacement(outpt.v.position, \
outpt.v.normal, \
outpt.v.patchCoord);
#if defined(DISPLACEMENT_HW_BILINEAR) \
|| defined(DISPLACEMENT_BILINEAR) \
|| defined(DISPLACEMENT_BIQUADRATIC) \
|| defined(NORMAL_HW_SCREENSPACE) \
|| defined(NORMAL_SCREENSPACE) \
|| defined(NORMAL_BIQUADRATIC) \
|| defined(NORMAL_BIQUADRATIC_WG)
uniform sampler2DArray textureDisplace_Data;
uniform samplerBuffer textureDisplace_Packing;
uniform isamplerBuffer textureDisplace_Pages;
uniform isamplerBuffer textureDisplace_Packing;
#endif
vec4 displacement(vec4 position, vec3 normal, vec4 patchCoord)
{
float disp = PTexLookup(patchCoord,
textureDisplace_Data,
textureDisplace_Packing,
textureDisplace_Pages).x;
return position + vec4(disp * normal, 0);
}
#if defined(DISPLACEMENT_HW_BILINEAR)
float disp = PtexLookupFast(patchCoord,
textureDisplace_Data,
textureDisplace_Packing).x;
#elif defined(DISPLACEMENT_BILINEAR)
float disp = PtexMipmapLookup(patchCoord,
mipmapBias,
textureDisplace_Data,
textureDisplace_Packing).x;
#elif defined(DISPLACEMENT_BIQUADRATIC)
float disp = PtexMipmapLookupQuadratic(patchCoord,
mipmapBias,
textureDisplace_Data,
textureDisplace_Packing).x;
#else
float disp = 0.0;
#endif
return position + vec4(disp * normal, 0) * displacementScale;
}
//--------------------------------------------------------------
// Vertex Shader
@ -98,8 +110,6 @@ void main()
//--------------------------------------------------------------
#ifdef GEOMETRY_SHADER
//uniform int nonAdaptiveLevel;
#ifdef PRIM_QUAD
layout(lines_adjacency) in;
@ -176,16 +186,10 @@ void emit(int index, vec4 position, vec3 normal, vec4 patchCoord, vec4 edgeVerts
// --------------------------------------
vec4 GeneratePatchCoord(vec2 localUV) // for non-adpative
vec4 GeneratePatchCoord(vec2 uv, int primitiveID) // for non-adaptive
{
ivec2 ptexIndex = texelFetch(OsdPatchParamBuffer, gl_PrimitiveID).xy;
int faceID = ptexIndex.x;
int lv = 1 << ((ptexIndex.y & 0xf) - ((ptexIndex.y >> 4) & 1));
int u = (ptexIndex.y >> 17) & 0x3ff;
int v = (ptexIndex.y >> 7) & 0x3ff;
vec2 uv = localUV;
uv = (uv * vec2(1.0)/lv) + vec2(u, v)/lv;
return vec4(uv.x, uv.y, lv+0.5, faceID+0.5);
ivec3 patchParam = OsdGetPatchParam(OsdGetPatchIndex(primitiveID));
return OsdInterpolatePatchCoord(uv, OsdGetPatchCoord(patchParam));
}
void main()
@ -198,12 +202,12 @@ void main()
vec3 normal[4];
// need to generate patch coord for non-patch quads
patchCoord[0] = GeneratePatchCoord(vec2(0, 0));
patchCoord[1] = GeneratePatchCoord(vec2(1, 0));
patchCoord[2] = GeneratePatchCoord(vec2(1, 1));
patchCoord[3] = GeneratePatchCoord(vec2(0, 1));
patchCoord[0] = GeneratePatchCoord(vec2(0, 0), gl_PrimitiveID);
patchCoord[1] = GeneratePatchCoord(vec2(1, 0), gl_PrimitiveID);
patchCoord[2] = GeneratePatchCoord(vec2(1, 1), gl_PrimitiveID);
patchCoord[3] = GeneratePatchCoord(vec2(0, 1), gl_PrimitiveID);
#ifdef USE_PTEX_DISPLACEMENT
#if defined(DISPLACEMENT_HW_BILINEAR) || defined(DISPLACEMENT_BILINEAR) || defined(DISPLACEMENT_BIQUADRATIC)
position[0] = displacement(vPosition[0], vNormal[0], patchCoord[0]);
position[1] = displacement(vPosition[1], vNormal[1], patchCoord[1]);
position[2] = displacement(vPosition[2], vNormal[2], patchCoord[2]);
@ -215,11 +219,10 @@ void main()
position[3] = vPosition[3];
#endif
#ifdef FLAT_NORMALS
// XXX: need to use vec C to get triangle normal.
#ifdef NORMAL_FACET
// emit flat normals for displaced surface
vec3 A = (position[0] - position[1]).xyz;
vec3 B = (position[3] - position[1]).xyz;
vec3 C = (position[2] - position[1]).xyz;
vec3 B = (position[2] - position[1]).xyz;
normal[0] = normalize(cross(B, A));
normal[1] = normal[0];
normal[2] = normal[0];
@ -266,7 +269,7 @@ void main()
patchCoord[1] = vPatchCoord[1];
patchCoord[2] = vPatchCoord[2];
#ifdef USE_PTEX_DISPLACEMENT
#if defined(DISPLACEMENT_HW_BILINEAR) || defined(DISPLACEMENT_BILINEAR) || defined(DISPLACEMENT_BIQUADRATIC)
position[0] = displacement(vPosition[0], vNormal[0], patchCoord[0]);
position[1] = displacement(vPosition[1], vNormal[1], patchCoord[1]);
position[2] = displacement(vPosition[2], vNormal[2], patchCoord[2]);
@ -276,16 +279,17 @@ void main()
position[2] = vPosition[2];
#endif
#ifdef FLAT_NORMALS // emit flat normals for displaced surface
#ifdef NORMAL_FACET
// emit flat normals for displaced surface
vec3 A = (position[0] - position[1]).xyz;
vec3 B = (position[2] - position[1]).xyz;
normal[0] = normalize(cross(B, A));
normal[1] = normal[0];
normal[2] = normal[0];
#else
normal[0] = gNormal[0];
normal[1] = gNormal[1];
normal[2] = gNormal[2];
normal[0] = vNormal[0];
normal[1] = vNormal[1];
normal[2] = vNormal[2];
#endif
#if defined(GEOMETRY_OUT_WIRE) || defined(GEOMETRY_OUT_LINE)
@ -322,49 +326,28 @@ in vec4 gPosition;
in vec3 gNormal;
in vec4 gPatchCoord;
noperspective in vec4 gEdgeDistance;
out vec4 outColor;
uniform int ptexFaceOffset;
#ifdef USE_PTEX_COLOR
#if defined(COLOR_PTEX_NEAREST) || defined(COLOR_PTEX_HW_BILINEAR) || \
defined(COLOR_PTEX_BILINEAR) || defined(COLOR_PTEX_BIQUADRATIC)
uniform sampler2DArray textureImage_Data;
uniform samplerBuffer textureImage_Packing;
uniform isamplerBuffer textureImage_Pages;
uniform isamplerBuffer textureImage_Packing;
#endif
#ifdef USE_PTEX_OCCLUSION
uniform sampler2DArray textureOcclusion_Data;
uniform samplerBuffer textureOcclusion_Packing;
uniform isamplerBuffer textureOcclusion_Pages;
#endif
#ifdef USE_PTEX_SPECULAR
uniform sampler2DArray textureSpecular_Data;
uniform samplerBuffer textureSpecular_Packing;
uniform isamplerBuffer textureSpecular_Pages;
#endif
#define NUM_LIGHTS 2
struct LightSource {
vec4 position;
vec4 ambient;
vec4 diffuse;
vec4 specular;
};
layout(std140) uniform Lighting {
LightSource lightSource[NUM_LIGHTS];
};
uniform bool overrideColorEnable = false;
uniform vec4 overrideColor;
#ifdef USE_PTEX_NORMAL
uniform sampler2DArray textureDisplace_Data;
uniform samplerBuffer textureDisplace_Packing;
uniform isamplerBuffer textureDisplace_Pages;
#if defined(NORMAL_HW_SCREENSPACE) || defined(NORMAL_SCREENSPACE)
vec3
perturbNormalFromDisplacement(vec3 position, vec3 normal, vec4 patchCoord)
@ -394,9 +377,15 @@ perturbNormalFromDisplacement(vec3 position, vec3 normal, vec4 patchCoord)
vec4 STll = patchCoord;
vec4 STlr = patchCoord + d * vec4(texDx.x, texDx.y, 0, 0);
vec4 STul = patchCoord + d * vec4(texDy.x, texDy.y, 0, 0);
float Hll = PTexLookup(STll, textureDisplace_Data, textureDisplace_Packing, textureDisplace_Pages).x;
float Hlr = PTexLookup(STlr, textureDisplace_Data, textureDisplace_Packing, textureDisplace_Pages).x;
float Hul = PTexLookup(STul, textureDisplace_Data, textureDisplace_Packing, textureDisplace_Pages).x;
#if defined NORMAL_HW_SCREENSPACE
float Hll = PtexLookupFast(STll, textureDisplace_Data, textureDisplace_Packing).x * displacementScale;
float Hlr = PtexLookupFast(STlr, textureDisplace_Data, textureDisplace_Packing).x * displacementScale;
float Hul = PtexLookupFast(STul, textureDisplace_Data, textureDisplace_Packing).x * displacementScale;
#elif defined NORMAL_SCREENSPACE
float Hll = PtexMipmapLookup(STll, mipmapBias, textureDisplace_Data, textureDisplace_Packing).x * displacementScale;
float Hlr = PtexMipmapLookup(STlr, mipmapBias, textureDisplace_Data, textureDisplace_Packing).x * displacementScale;
float Hul = PtexMipmapLookup(STul, mipmapBias, textureDisplace_Data, textureDisplace_Packing).x * displacementScale;
#endif
float dBs = (Hlr - Hll)/d;
float dBt = (Hul - Hll)/d;
#endif
@ -419,22 +408,11 @@ vec4 getEnvironmentHDR(sampler2D sampler, vec3 dir)
}
vec4
lighting(vec3 Peye, vec3 Neye, float spec)
lighting(vec4 texColor, vec3 Peye, vec3 Neye, float spec, float occ)
{
vec4 color = vec4(0);
#ifdef USE_PTEX_OCCLUSION
float occ = PTexLookup(gPatchCoord,
textureOcclusion_Data,
textureOcclusion_Packing,
textureOcclusion_Pages).x;
#else
float occ = 0.0;
#endif
vec3 n = Neye;
for (int i = 0; i < NUM_LIGHTS; ++i) {
vec4 Plight = lightSource[i].position;
@ -444,11 +422,11 @@ lighting(vec3 Peye, vec3 Neye, float spec)
vec3 h = normalize(l + vec3(0,0,1)); // directional viewer
float d = max(0.0, dot(n, l));
float s = 0.0; //pow(max(0.0, dot(n, h)), 16.0f);
float s = pow(max(0.0, dot(n, h)), 64.0f);
color += (1.0-occ) * ((lightSource[i].ambient +
d * lightSource[i].diffuse +
spec * s * lightSource[i].specular));
d * lightSource[i].diffuse) * texColor +
spec * s * lightSource[i].specular);
}
color.a = 1;
@ -457,7 +435,7 @@ lighting(vec3 Peye, vec3 Neye, float spec)
}
vec4
edgeColor(vec4 Cfill, vec4 edgeDistance)
edgeColor(vec4 Cfill)
{
#if defined(GEOMETRY_OUT_WIRE) || defined(GEOMETRY_OUT_LINE)
#ifdef PRIM_TRI
@ -468,6 +446,9 @@ edgeColor(vec4 Cfill, vec4 edgeDistance)
float d =
min(min(gEdgeDistance[0], gEdgeDistance[1]),
min(gEdgeDistance[2], gEdgeDistance[3]));
#endif
#ifdef PRIM_LINE
float d = 0;
#endif
vec4 Cedge = vec4(1.0, 1.0, 0.0, 1.0);
float p = exp2(-2 * d * d);
@ -481,20 +462,13 @@ edgeColor(vec4 Cfill, vec4 edgeDistance)
return Cfill;
}
void
main()
{
#ifdef USE_PTEX_COLOR
vec4 texColor = PTexLookup(gPatchCoord,
textureImage_Data,
textureImage_Packing,
textureImage_Pages);
// texColor = vec4(pow(texColor.xyz, vec3(0.4545)), 1);
#else
vec4 texColor = vec4(1);
#endif
// ------------ normal ---------------
#ifdef USE_PTEX_NORMAL
#if defined(NORMAL_HW_SCREENSPACE) || defined(NORMAL_SCREENSPACE)
vec3 normal = perturbNormalFromDisplacement(gPosition.xyz,
gNormal,
gPatchCoord);
@ -502,54 +476,70 @@ main()
vec3 normal = gNormal;
#endif
#if 0
if (overrideColorEnable) {
texColor = overrideColor;
vec4 Cf = texColor * lighting(gPosition.xyz, normal);
outColor = edgeColor(Cf, gEdgeDistance);
return;
}
// ------------ color ---------------
#if defined COLOR_PTEX_NEAREST
vec4 texColor = PtexLookupNearest(gPatchCoord,
textureImage_Data,
textureImage_Packing);
#elif defined COLOR_PTEX_HW_BILINEAR
vec4 texColor = PtexLookupFast(gPatchCoord,
textureImage_Data,
textureImage_Packing);
#elif defined COLOR_PTEX_BILINEAR
vec4 texColor = PtexMipmapLookup(gPatchCoord,
mipmapBias,
textureImage_Data,
textureImage_Packing);
#elif defined COLOR_PTEX_BIQUADRATIC
vec4 texColor = PtexMipmapLookupQuadratic(gPatchCoord,
mipmapBias,
textureImage_Data,
textureImage_Packing);
#elif defined COLOR_PATCHTYPE
vec4 texColor = edgeColor(lighting(GetOverrideColor(OsdGetPatchParam(OsdGetPatchIndex(gl_PrimitiveID))),
gPosition.xyz, normal, 1, 0));
outColor = texColor;
return;
#elif defined COLOR_PATCHCOORD
vec4 texColor = edgeColor(lighting(gPatchCoord, gPosition.xyz, normal, 1, 0));
outColor = texColor;
return;
#elif defined COLOR_NORMAL
vec4 texColor = edgeColor(vec4(normal, 1));
outColor = texColor;
return;
#else // COLOR_NONE
vec4 texColor = vec4(0.5);
#endif
#ifdef USE_IBL
// ------------ occlusion ---------------
#ifdef USE_PTEX_OCCLUSION
float occ = PTexLookup(gPatchCoord,
textureOcclusion_Data,
textureOcclusion_Packing,
textureOcclusion_Pages).x;
float occ = PtexMipmapLookup(gPatchCoord,
mipmapBias,
textureOcclusion_Data,
textureOcclusion_Packing).x;
#else
float occ = 0.0;
#endif
// ------------ specular ---------------
#ifdef USE_PTEX_SPECULAR
float specular = PTexLookup(gPatchCoord,
textureSpecular_Data,
textureSpecular_Packing,
textureSpecular_Pages).x;
float specular = PtexMipmapLookup(gPatchCoord,
mipmapBias,
textureSpecular_Data,
textureSpecular_Packing).x;
#else
float specular = 1.0;
#endif
vec4 a = vec4(0, 0, 0, 1); //ambientColor;
vec4 d = getEnvironmentHDR(diffuseEnvironmentMap, normal) * 1.4;
vec3 eye = normalize(gPosition.xyz - vec3(0,0,0));
vec3 reflect = reflect(eye, normal);
vec4 s = getEnvironmentHDR(specularEnvironmentMap, reflect);
const float fresnelBias = 0;
const float fresnelScale = 1.0;
const float fresnelPower = 2.0;
float fresnel = fresnelBias + fresnelScale * pow(1.0+dot(normal,eye), fresnelPower);
vec4 Cf = lighting(texColor, gPosition.xyz, normal, specular, occ);
a *= (1.0-occ);
d *= (1.0-occ);
s *= min(specular, (1.0-occ)) * fresnel;
// ------------ wireframe ---------------
vec4 Cf = (a + d) * texColor + s * 0.5;
#else
vec4 Cf = texColor * lighting(gPosition.xyz, normal, specular);
#endif
outColor = edgeColor(Cf, gEdgeDistance);
outColor = edgeColor(Cf);
}
#endif

View File

@ -43,7 +43,6 @@ GLFWwindow* g_window=0;
GLFWmonitor* g_primary=0;
#include <osd/glDrawContext.h>
#include <osd/glDrawRegistry.h>
#include <osd/glMesh.h>
#include <far/error.h>
#include <far/stencilTables.h>
@ -94,7 +93,9 @@ GLFWmonitor* g_primary=0;
#include "../common/stopwatch.h"
#include "../common/simple_math.h"
#include "../common/gl_hud.h"
#include "../common/glShaderCache.h"
#include <osd/glslPatchShaderSource.h>
static const char *shaderSource =
#include "shader.gen.h"
;
@ -796,6 +797,12 @@ union Effect {
}
};
static Effect
GetEffect() {
return Effect(g_displayStyle);
}
struct EffectDesc {
EffectDesc(OpenSubdiv::Far::PatchDescriptor desc,
Effect effect) : desc(desc), effect(effect),
@ -813,202 +820,150 @@ struct EffectDesc {
}
};
class EffectDrawRegistry : public Osd::GLDrawRegistry<EffectDesc> {
class ShaderCache : public GLShaderCache<EffectDesc> {
public:
virtual GLDrawConfig *CreateDrawConfig(EffectDesc const &effectDesc) {
protected:
virtual ConfigType *
_CreateDrawConfig(EffectDesc const & desc, SourceConfigType const * sconfig);
virtual SourceConfigType *
_CreateDrawSourceConfig(EffectDesc const & desc);
};
EffectDrawRegistry::SourceConfigType *
EffectDrawRegistry::_CreateDrawSourceConfig(EffectDesc const & effectDesc) {
Effect effect = effectDesc.effect;
SourceConfigType * sconfig =
BaseRegistry::_CreateDrawSourceConfig(effectDesc.desc);
assert(sconfig);
using namespace OpenSubdiv;
// compile shader program
#if defined(GL_ARB_tessellation_shader) || defined(GL_VERSION_4_0)
const char *glslVersion = "#version 400\n";
const char *glslVersion = "#version 400\n";
#else
const char *glslVersion = "#version 330\n";
const char *glslVersion = "#version 330\n";
#endif
GLDrawConfig *config = new GLDrawConfig(glslVersion);
// legacy gregory patch requires OSD_MAX_VALENCE and OSD_NUM_ELEMENTS defined
if (effectDesc.desc.GetType() == Far::PatchDescriptor::GREGORY or
effectDesc.desc.GetType() == Far::PatchDescriptor::GREGORY_BOUNDARY) {
std::ostringstream ss;
ss << effectDesc.maxValence;
sconfig->commonShader.AddDefine("OSD_MAX_VALENCE", ss.str());
ss.str("");
Far::PatchDescriptor::Type type = effectDesc.desc.GetType();
ss << effectDesc.numElements;
sconfig->commonShader.AddDefine("OSD_NUM_ELEMENTS", ss.str());
}
std::string primTypeDefine =
(type == Far::PatchDescriptor::QUADS ?
"#define PRIM_QUAD\n" : "#define PRIM_TRI\n");
if (effectDesc.desc.GetType() == Far::PatchDescriptor::QUADS or
effectDesc.desc.GetType() == Far::PatchDescriptor::TRIANGLES) {
sconfig->vertexShader.source = shaderSource;
sconfig->vertexShader.version = glslVersion;
sconfig->vertexShader.AddDefine("VERTEX_SHADER");
} else {
sconfig->geometryShader.AddDefine("SMOOTH_NORMALS");
}
// common defines
std::stringstream ss;
sconfig->geometryShader.source = shaderSource;
sconfig->geometryShader.version = glslVersion;
sconfig->geometryShader.AddDefine("GEOMETRY_SHADER");
sconfig->fragmentShader.source = shaderSource;
sconfig->fragmentShader.version = glslVersion;
sconfig->fragmentShader.AddDefine("FRAGMENT_SHADER");
if (effectDesc.desc.GetType() == Far::PatchDescriptor::QUADS) {
// uniform catmark, bilinear
sconfig->geometryShader.AddDefine("PRIM_QUAD");
sconfig->fragmentShader.AddDefine("PRIM_QUAD");
sconfig->commonShader.AddDefine("UNIFORM_SUBDIVISION");
} else if (effectDesc.desc.GetType() == Far::PatchDescriptor::TRIANGLES) {
// uniform loop
sconfig->geometryShader.AddDefine("PRIM_TRI");
sconfig->fragmentShader.AddDefine("PRIM_TRI");
sconfig->commonShader.AddDefine("LOOP");
sconfig->commonShader.AddDefine("UNIFORM_SUBDIVISION");
} else {
// adaptive
sconfig->vertexShader.source = shaderSource + sconfig->vertexShader.source;
sconfig->tessControlShader.source = shaderSource + sconfig->tessControlShader.source;
sconfig->tessEvalShader.source = shaderSource + sconfig->tessEvalShader.source;
sconfig->geometryShader.AddDefine("PRIM_TRI");
sconfig->fragmentShader.AddDefine("PRIM_TRI");
}
switch (effect.displayStyle) {
// display styles
switch (effectDesc.effect.displayStyle) {
case kWire:
sconfig->commonShader.AddDefine("GEOMETRY_OUT_WIRE");
ss << "#define GEOMETRY_OUT_WIRE\n";
break;
case kWireShaded:
sconfig->commonShader.AddDefine("GEOMETRY_OUT_LINE");
ss << "#define GEOMETRY_OUT_LINE\n";
break;
case kShaded:
sconfig->commonShader.AddDefine("GEOMETRY_OUT_FILL");
ss << "#define GEOMETRY_OUT_FILL\n";
break;
case kVarying:
sconfig->commonShader.AddDefine("VARYING_COLOR");
sconfig->commonShader.AddDefine("GEOMETRY_OUT_FILL");
ss << "#define VARYING_COLOR\n";
ss << "#define GEOMETRY_OUT_FILL\n";
break;
case kVaryingInterleaved:
sconfig->commonShader.AddDefine("VARYING_COLOR");
sconfig->commonShader.AddDefine("GEOMETRY_OUT_FILL");
ss << "#define VARYING_COLOR\n";
ss << "#define GEOMETRY_OUT_FILL\n";
break;
}
// for legacy gregory
ss << "#define OSD_MAX_VALENCE " << effectDesc.maxValence << "\n";
ss << "#define OSD_NUM_ELEMENTS " << effectDesc.numElements << "\n";
// include osd PatchCommon
ss << Osd::GLSLPatchShaderSource::GetCommonShaderSource();
std::string common = ss.str();
ss.str("");
// vertex shader
ss << common
<< (effectDesc.desc.IsAdaptive() ? "" : "#define VERTEX_SHADER\n")
<< shaderSource
<< Osd::GLSLPatchShaderSource::GetVertexShaderSource(type);
config->CompileAndAttachShader(GL_VERTEX_SHADER, ss.str());
ss.str("");
if (effectDesc.desc.IsAdaptive()) {
// tess control shader
ss << common
<< shaderSource
<< Osd::GLSLPatchShaderSource::GetTessControlShaderSource(type);
config->CompileAndAttachShader(GL_TESS_CONTROL_SHADER, ss.str());
ss.str("");
// tess eval shader
ss << common
<< shaderSource
<< Osd::GLSLPatchShaderSource::GetTessEvalShaderSource(type);
config->CompileAndAttachShader(GL_TESS_EVALUATION_SHADER, ss.str());
ss.str("");
}
// geometry shader
ss << common
<< "#define GEOMETRY_SHADER\n" // for my shader source
<< primTypeDefine
<< shaderSource;
config->CompileAndAttachShader(GL_GEOMETRY_SHADER, ss.str());
ss.str("");
// fragment shader
ss << common
<< "#define FRAGMENT_SHADER\n" // for my shader source
<< primTypeDefine
<< shaderSource;
config->CompileAndAttachShader(GL_FRAGMENT_SHADER, ss.str());
ss.str("");
if (!config->Link()) {
delete config;
return NULL;
}
// assign uniform locations
GLuint uboIndex;
GLuint program = config->GetProgram();
g_transformBinding = 0;
uboIndex = glGetUniformBlockIndex(program, "Transform");
if (uboIndex != GL_INVALID_INDEX)
glUniformBlockBinding(program, uboIndex, g_transformBinding);
g_tessellationBinding = 1;
uboIndex = glGetUniformBlockIndex(program, "Tessellation");
if (uboIndex != GL_INVALID_INDEX)
glUniformBlockBinding(program, uboIndex, g_tessellationBinding);
g_lightingBinding = 2;
uboIndex = glGetUniformBlockIndex(program, "Lighting");
if (uboIndex != GL_INVALID_INDEX)
glUniformBlockBinding(program, uboIndex, g_lightingBinding);
// assign texture locations
GLint loc;
if ((loc = glGetUniformLocation(program, "OsdVertexBuffer")) != -1) {
glProgramUniform1i(program, loc, 0); // GL_TEXTURE0
}
if ((loc = glGetUniformLocation(program, "OsdValenceBuffer")) != -1) {
glProgramUniform1i(program, loc, 1); // GL_TEXTURE1
}
if ((loc = glGetUniformLocation(program, "OsdQuadOffsetBuffer")) != -1) {
glProgramUniform1i(program, loc, 2); // GL_TEXTURE2
}
if ((loc = glGetUniformLocation(program, "OsdPatchParamBuffer")) != -1) {
glProgramUniform1i(program, loc, 3); // GL_TEXTURE3
}
if ((loc = glGetUniformLocation(program, "OsdFVarDataBuffer")) != -1) {
glProgramUniform1i(program, loc, 4); // GL_TEXTURE4
}
return config;
}
};
return sconfig;
}
EffectDrawRegistry::ConfigType *
EffectDrawRegistry::_CreateDrawConfig(
DescType const & desc,
SourceConfigType const * sconfig) {
ConfigType * config = BaseRegistry::_CreateDrawConfig(desc.desc, sconfig);
assert(config);
GLuint uboIndex;
// XXXdyu can use layout(binding=) with GLSL 4.20 and beyond
g_transformBinding = 0;
uboIndex = glGetUniformBlockIndex(config->program, "Transform");
if (uboIndex != GL_INVALID_INDEX)
glUniformBlockBinding(config->program, uboIndex, g_transformBinding);
g_tessellationBinding = 1;
uboIndex = glGetUniformBlockIndex(config->program, "Tessellation");
if (uboIndex != GL_INVALID_INDEX)
glUniformBlockBinding(config->program, uboIndex, g_tessellationBinding);
g_lightingBinding = 2;
uboIndex = glGetUniformBlockIndex(config->program, "Lighting");
if (uboIndex != GL_INVALID_INDEX)
glUniformBlockBinding(config->program, uboIndex, g_lightingBinding);
GLint loc;
#if not defined(GL_ARB_separate_shader_objects) || defined(GL_VERSION_4_1)
glUseProgram(config->program);
if ((loc = glGetUniformLocation(config->program, "OsdVertexBuffer")) != -1) {
glUniform1i(loc, 0); // GL_TEXTURE0
}
if ((loc = glGetUniformLocation(config->program, "OsdValenceBuffer")) != -1) {
glUniform1i(loc, 1); // GL_TEXTURE1
}
if ((loc = glGetUniformLocation(config->program, "OsdQuadOffsetBuffer")) != -1) {
glUniform1i(loc, 2); // GL_TEXTURE2
}
if ((loc = glGetUniformLocation(config->program, "OsdPatchParamBuffer")) != -1) {
glUniform1i(loc, 3); // GL_TEXTURE3
}
if ((loc = glGetUniformLocation(config->program, "OsdFVarDataBuffer")) != -1) {
glUniform1i(loc, 4); // GL_TEXTURE4
}
#else
if ((loc = glGetUniformLocation(config->program, "OsdVertexBuffer")) != -1) {
glProgramUniform1i(config->program, loc, 0); // GL_TEXTURE0
}
if ((loc = glGetUniformLocation(config->program, "OsdValenceBuffer")) != -1) {
glProgramUniform1i(config->program, loc, 1); // GL_TEXTURE1
}
if ((loc = glGetUniformLocation(config->program, "OsdQuadOffsetBuffer")) != -1) {
glProgramUniform1i(config->program, loc, 2); // GL_TEXTURE2
}
if ((loc = glGetUniformLocation(config->program, "OsdPatchParamBuffer")) != -1) {
glProgramUniform1i(config->program, loc, 3); // GL_TEXTURE3
}
if ((loc = glGetUniformLocation(config->program, "OsdFVarDataBuffer")) != -1) {
glProgramUniform1i(config->program, loc, 4); // GL_TEXTURE4
}
#endif
return config;
}
EffectDrawRegistry effectRegistry;
static Effect
GetEffect() {
return Effect(g_displayStyle);
}
ShaderCache g_shaderCache;
//------------------------------------------------------------------------------
static GLuint
bindProgram(Effect effect, Osd::DrawContext::PatchArray const & patch) {
EffectDesc effectDesc(patch.GetDescriptor(), effect);
// only legacy gregory needs maxValence and numElements
int maxValence = g_topology->GetDrawContext()->GetMaxValence();
int numElements = (g_displayStyle == kVaryingInterleaved ? 7 : 3);
typedef OpenSubdiv::Far::PatchDescriptor Descriptor;
if (patch.GetDescriptor().GetType() == Descriptor::GREGORY or
patch.GetDescriptor().GetType() == Descriptor::GREGORY_BOUNDARY) {
effectDesc.maxValence = maxValence;
effectDesc.numElements = numElements;
}
EffectDrawRegistry::ConfigType *
config = effectRegistry.GetDrawConfig(effectDesc);
GLuint program = config->program;
glUseProgram(program);
static void
updateUniformBlocks() {
if (! g_transformUB) {
glGenBuffers(1, &g_transformUB);
glBindBuffer(GL_UNIFORM_BUFFER, g_transformUB);
@ -1074,6 +1029,10 @@ bindProgram(Effect effect, Osd::DrawContext::PatchArray const & patch) {
glBindBufferBase(GL_UNIFORM_BUFFER, g_lightingBinding, g_lightingUB);
}
static void
bindTextures() {
Osd::GLDrawContext *drawContext = g_topology->GetDrawContext();
if (drawContext->GetVertexTextureBuffer()) {
@ -1104,7 +1063,73 @@ bindProgram(Effect effect, Osd::DrawContext::PatchArray const & patch) {
glActiveTexture(GL_TEXTURE0);
return program;
}
static GLenum
bindProgram(Effect effect,
Osd::DrawContext::PatchArray const & patch,
GLfloat const *color,
int baseVertex) {
EffectDesc effectDesc(patch.GetDescriptor(), effect);
typedef OpenSubdiv::Far::PatchDescriptor Descriptor;
if (patch.GetDescriptor().GetType() == Descriptor::GREGORY or
patch.GetDescriptor().GetType() == Descriptor::GREGORY_BOUNDARY) {
// only legacy gregory needs maxValence and numElements
int maxValence = g_topology->GetDrawContext()->GetMaxValence();
int numElements = (g_displayStyle == kVaryingInterleaved ? 7 : 3);
effectDesc.maxValence = maxValence;
effectDesc.numElements = numElements;
}
// lookup shader cache (compile the shader if needed)
GLDrawConfig *config = g_shaderCache.GetDrawConfig(effectDesc);
if (!config) return 0;
GLuint program = config->GetProgram();
glUseProgram(program);
// bind standalone uniforms
GLint uniformPrimitiveIdBase =
glGetUniformLocation(program, "PrimitiveIdBase");
if (uniformPrimitiveIdBase >=0)
glUniform1i(uniformPrimitiveIdBase, patch.GetPatchIndex());
GLint uniformColor = glGetUniformLocation(program, "diffuseColor");
if (uniformColor >= 0)
glUniform4f(uniformColor, color[0], color[1], color[2], 1);
// used by legacy gregory
GLint uniformBaseVertex = glGetUniformLocation(program, "BaseVertex");
if (uniformBaseVertex >= 0)
glUniform1i(uniformBaseVertex, baseVertex);
GLint uniformGregoryQuadOffsetBase =
glGetUniformLocation(program, "GregoryQuadOffsetBase");
if (uniformGregoryQuadOffsetBase >= 0)
glUniform1i(uniformGregoryQuadOffsetBase, patch.GetQuadOffsetIndex());
// return primtype
GLenum primType;
switch(effectDesc.desc.GetType()) {
case Descriptor::QUADS:
primType = GL_LINES_ADJACENCY;
break;
case Descriptor::TRIANGLES:
primType = GL_TRIANGLES;
break;
default:
#if defined(GL_ARB_tessellation_shader) || defined(GL_VERSION_4_0)
primType = GL_PATCHES;
glPatchParameteri(GL_PATCH_VERTICES, effectDesc.desc.GetNumControlVertices());
#else
primType = GL_POINTS;
#endif
break;
}
return primType;
}
//------------------------------------------------------------------------------
@ -1118,58 +1143,9 @@ drawPatches(Osd::DrawContext::PatchArrayVector const &patches,
Osd::DrawContext::PatchArray const & patch = patches[i];
Far::PatchDescriptor desc = patch.GetDescriptor();
Far::PatchDescriptor::Type patchType = desc.GetType();
GLenum primType;
switch(patchType) {
case Far::PatchDescriptor::QUADS:
primType = GL_LINES_ADJACENCY;
break;
case Far::PatchDescriptor::TRIANGLES:
primType = GL_TRIANGLES;
break;
default:
#if defined(GL_ARB_tessellation_shader) || defined(GL_VERSION_4_0)
primType = GL_PATCHES;
glPatchParameteri(GL_PATCH_VERTICES, desc.GetNumControlVertices());
#else
primType = GL_POINTS;
#endif
}
#if defined(GL_ARB_tessellation_shader) || defined(GL_VERSION_4_0)
GLuint program = bindProgram(GetEffect(), patch);
GLuint uniformColor =
glGetUniformLocation(program, "diffuseColor");
glProgramUniform4f(program, uniformColor, color[0], color[1], color[2], 1);
GLuint uniformGregoryQuadOffsetBase =
glGetUniformLocation(program, "GregoryQuadOffsetBase");
GLuint uniformPrimitiveIdBase =
glGetUniformLocation(program, "PrimitiveIdBase");
glProgramUniform1i(program, uniformGregoryQuadOffsetBase,
patch.GetQuadOffsetIndex());
glProgramUniform1i(program, uniformPrimitiveIdBase,
patch.GetPatchIndex());
#else
GLuint program = bindProgram(GetEffect(), patch);
GLint uniformPrimitiveIdBase =
glGetUniformLocation(program, "PrimitiveIdBase");
if (uniformPrimitiveIdBase != -1)
glUniform1i(uniformPrimitiveIdBase, patch.GetPatchIndex());
#endif
GLvoid *indices = (void *)(patch.GetVertIndex() * sizeof(unsigned int));
int baseVertex = g_topology->GetNumVertices() * instanceIndex;
glProgramUniform1i(program, glGetUniformLocation(program, "BaseVertex"),
baseVertex);
GLvoid *indices = (void *)(patch.GetVertIndex() * sizeof(unsigned int));
GLenum primType = bindProgram(GetEffect(), patch, color, baseVertex);
glDrawElementsBaseVertex(primType,
patch.GetNumIndices(),
@ -1259,6 +1235,9 @@ display() {
glBeginQuery(GL_TIME_ELAPSED, g_queries[1]);
#endif
updateUniformBlocks();
bindTextures();
// draw instances with same topology
for (int i = 0; i < g_numInstances; ++i) {
GLfloat color[3] = {i/(float)g_numInstances, 0.5, 0.5};

View File

@ -44,7 +44,6 @@ GLFWmonitor* g_primary=0;
#include <far/error.h>
#include <osd/glDrawContext.h>
#include <osd/glDrawRegistry.h>
#include <osd/cpuEvaluator.h>
#include <osd/cpuGLVertexBuffer.h>
@ -91,8 +90,9 @@ OpenSubdiv::Osd::GLMeshInterface *g_mesh;
#include "../common/simple_math.h"
#include "../common/gl_hud.h"
#include "../common/objAnim.h"
#include "../common/patchColors.h"
#include "../common/glShaderCache.h"
#include <osd/glslPatchShaderSource.h>
static const char *shaderSource =
#if defined(GL_ARB_tessellation_shader) || defined(GL_VERSION_4_0)
#include "shader.gen.h"
@ -803,6 +803,17 @@ union Effect {
}
};
static Effect
GetEffect()
{
return Effect(g_displayStyle,
g_screenSpaceTess,
g_fractionalSpacing,
g_patchCull);
}
// ---------------------------------------------------------------------------
struct EffectDesc {
EffectDesc(OpenSubdiv::Far::PatchDescriptor desc,
Effect effect) : desc(desc), effect(effect),
@ -820,220 +831,189 @@ struct EffectDesc {
}
};
class EffectDrawRegistry : public OpenSubdiv::Osd::GLDrawRegistry<EffectDesc> {
// ---------------------------------------------------------------------------
protected:
virtual ConfigType *
_CreateDrawConfig(EffectDesc const & desc, SourceConfigType const * sconfig);
class ShaderCache : public GLShaderCache<EffectDesc> {
public:
virtual GLDrawConfig *CreateDrawConfig(EffectDesc const &effectDesc) {
virtual SourceConfigType *
_CreateDrawSourceConfig(EffectDesc const & desc);
};
EffectDrawRegistry::SourceConfigType *
EffectDrawRegistry::_CreateDrawSourceConfig(EffectDesc const & effectDesc)
{
typedef OpenSubdiv::Far::PatchDescriptor Descriptor;
Effect effect = effectDesc.effect;
SourceConfigType * sconfig =
BaseRegistry::_CreateDrawSourceConfig(effectDesc.desc);
assert(sconfig);
using namespace OpenSubdiv;
// compile shader program
#if defined(GL_ARB_tessellation_shader) || defined(GL_VERSION_4_0)
const char *glslVersion = "#version 400\n";
const char *glslVersion = "#version 400\n";
#else
const char *glslVersion = "#version 330\n";
const char *glslVersion = "#version 330\n";
#endif
GLDrawConfig *config = new GLDrawConfig(glslVersion);
// legacy gregory patch requires OSD_MAX_VALENCE and OSD_NUM_ELEMENTS defined
if (effectDesc.desc.GetType() == Descriptor::GREGORY or
effectDesc.desc.GetType() == Descriptor::GREGORY_BOUNDARY) {
std::ostringstream ss;
ss << effectDesc.maxValence;
sconfig->commonShader.AddDefine("OSD_MAX_VALENCE", ss.str());
Far::PatchDescriptor::Type type = effectDesc.desc.GetType();
// common defines
std::stringstream ss;
if (type == Far::PatchDescriptor::QUADS) {
ss << "#define PRIM_QUAD\n";
} else {
ss << "#define PRIM_TRI\n";
}
// OSD tessellation controls
if (effectDesc.effect.screenSpaceTess) {
ss << "#define OSD_ENABLE_SCREENSPACE_TESSELLATION\n";
}
if (effectDesc.effect.fractionalSpacing) {
ss << "#define OSD_FRACTIONAL_ODD_SPACING\n";
}
if (effectDesc.effect.patchCull) {
ss << "#define OSD_ENABLE_PATCH_CULL\n";
}
if (g_singleCreasePatch) {
ss << "#define OSD_PATCH_ENABLE_SINGLE_CREASE\n";
}
// for legacy gregory
ss << "#define OSD_MAX_VALENCE " << effectDesc.maxValence << "\n";
ss << "#define OSD_NUM_ELEMENTS " << effectDesc.numElements << "\n";
// display styles
switch (effectDesc.effect.displayStyle) {
case kWire:
ss << "#define GEOMETRY_OUT_WIRE\n";
break;
case kWireShaded:
ss << "#define GEOMETRY_OUT_LINE\n";
break;
case kShaded:
ss << "#define GEOMETRY_OUT_FILL\n";
break;
case kVaryingColor:
ss << "#define VARYING_COLOR\n";
ss << "#define GEOMETRY_OUT_FILL\n";
break;
case kInterleavedVaryingColor:
ss << "#define VARYING_COLOR\n";
ss << "#define GEOMETRY_OUT_FILL\n";
break;
case kFaceVaryingColor:
ss << "#define OSD_FVAR_WIDTH 2\n";
ss << "#define FACEVARYING_COLOR\n";
ss << "#define GEOMETRY_OUT_FILL\n";
break;
}
if (effectDesc.desc.IsAdaptive()) {
ss << "#define SMOOTH_NORMALS\n";
} else {
ss << "#define UNIFORM_SUBDIVISION\n";
}
if (type == Far::PatchDescriptor::TRIANGLES) {
ss << "#define LOOP\n";
}
// need for patch color-coding : we need these defines in the fragment shader
if (type == Far::PatchDescriptor::GREGORY) {
ss << "#define OSD_PATCH_GREGORY\n";
} else if (type == Far::PatchDescriptor::GREGORY_BOUNDARY) {
ss << "#define OSD_PATCH_GREGORY_BOUNDARY\n";
} else if (type == Far::PatchDescriptor::GREGORY_BASIS) {
ss << "#define OSD_PATCH_GREGORY_BASIS\n";
}
// include osd PatchCommon
ss << Osd::GLSLPatchShaderSource::GetCommonShaderSource();
std::string common = ss.str();
ss.str("");
ss << effectDesc.numElements;
sconfig->commonShader.AddDefine("OSD_NUM_ELEMENTS", ss.str());
// vertex shader
ss << common
// enable local vertex shader
<< (effectDesc.desc.IsAdaptive() ? "" : "#define VERTEX_SHADER\n")
<< shaderSource
<< Osd::GLSLPatchShaderSource::GetVertexShaderSource(type);
config->CompileAndAttachShader(GL_VERTEX_SHADER, ss.str());
ss.str("");
if (effectDesc.desc.IsAdaptive()) {
// tess control shader
ss << common
<< shaderSource
<< Osd::GLSLPatchShaderSource::GetTessControlShaderSource(type);
config->CompileAndAttachShader(GL_TESS_CONTROL_SHADER, ss.str());
ss.str("");
// tess eval shader
ss << common
<< shaderSource
<< Osd::GLSLPatchShaderSource::GetTessEvalShaderSource(type);
config->CompileAndAttachShader(GL_TESS_EVALUATION_SHADER, ss.str());
ss.str("");
}
// geometry shader
ss << common
<< "#define GEOMETRY_SHADER\n"
<< shaderSource;
config->CompileAndAttachShader(GL_GEOMETRY_SHADER, ss.str());
ss.str("");
// fragment shader
ss << common
<< "#define FRAGMENT_SHADER\n"
<< shaderSource;
config->CompileAndAttachShader(GL_FRAGMENT_SHADER, ss.str());
ss.str("");
if (!config->Link()) {
delete config;
return NULL;
}
// assign uniform locations
GLuint uboIndex;
GLuint program = config->GetProgram();
g_transformBinding = 0;
uboIndex = glGetUniformBlockIndex(program, "Transform");
if (uboIndex != GL_INVALID_INDEX)
glUniformBlockBinding(program, uboIndex, g_transformBinding);
g_tessellationBinding = 1;
uboIndex = glGetUniformBlockIndex(program, "Tessellation");
if (uboIndex != GL_INVALID_INDEX)
glUniformBlockBinding(program, uboIndex, g_tessellationBinding);
g_lightingBinding = 2;
uboIndex = glGetUniformBlockIndex(program, "Lighting");
if (uboIndex != GL_INVALID_INDEX)
glUniformBlockBinding(program, uboIndex, g_lightingBinding);
// assign texture locations
GLint loc;
glUseProgram(program);
if ((loc = glGetUniformLocation(program, "OsdVertexBuffer")) != -1) {
glUniform1i(loc, 0); // GL_TEXTURE0
}
if ((loc = glGetUniformLocation(program, "OsdValenceBuffer")) != -1) {
glUniform1i(loc, 1); // GL_TEXTURE1
}
if ((loc = glGetUniformLocation(program, "OsdQuadOffsetBuffer")) != -1) {
glUniform1i(loc, 2); // GL_TEXTURE2
}
if ((loc = glGetUniformLocation(program, "OsdPatchParamBuffer")) != -1) {
glUniform1i(loc, 3); // GL_TEXTURE3
}
if ((loc = glGetUniformLocation(program, "OsdFVarDataBuffer")) != -1) {
glUniform1i(loc, 4); // GL_TEXTURE4
}
glUseProgram(0);
return config;
}
};
if (effectDesc.desc.GetType() == Descriptor::QUADS or
effectDesc.desc.GetType() == Descriptor::TRIANGLES) {
sconfig->vertexShader.source = shaderSource;
sconfig->vertexShader.version = glslVersion;
sconfig->vertexShader.AddDefine("VERTEX_SHADER");
} else {
sconfig->geometryShader.AddDefine("SMOOTH_NORMALS");
}
sconfig->geometryShader.source = shaderSource;
sconfig->geometryShader.version = glslVersion;
sconfig->geometryShader.AddDefine("GEOMETRY_SHADER");
sconfig->fragmentShader.source = shaderSource;
sconfig->fragmentShader.version = glslVersion;
sconfig->fragmentShader.AddDefine("FRAGMENT_SHADER");
if (effectDesc.desc.GetType() == Descriptor::QUADS) {
// uniform catmark, bilinear
sconfig->geometryShader.AddDefine("PRIM_QUAD");
sconfig->fragmentShader.AddDefine("PRIM_QUAD");
sconfig->commonShader.AddDefine("UNIFORM_SUBDIVISION");
} else if (effectDesc.desc.GetType() == Descriptor::TRIANGLES) {
// uniform loop
sconfig->geometryShader.AddDefine("PRIM_TRI");
sconfig->fragmentShader.AddDefine("PRIM_TRI");
sconfig->commonShader.AddDefine("LOOP");
sconfig->commonShader.AddDefine("UNIFORM_SUBDIVISION");
} else {
// adaptive
sconfig->vertexShader.source = shaderSource + sconfig->vertexShader.source;
sconfig->tessControlShader.source = shaderSource + sconfig->tessControlShader.source;
sconfig->tessEvalShader.source = shaderSource + sconfig->tessEvalShader.source;
sconfig->geometryShader.AddDefine("PRIM_TRI");
sconfig->fragmentShader.AddDefine("PRIM_TRI");
}
if (effect.screenSpaceTess) {
sconfig->commonShader.AddDefine("OSD_ENABLE_SCREENSPACE_TESSELLATION");
}
if (effect.fractionalSpacing) {
sconfig->commonShader.AddDefine("OSD_FRACTIONAL_ODD_SPACING");
}
if (effect.patchCull) {
sconfig->commonShader.AddDefine("OSD_ENABLE_PATCH_CULL");
}
switch (effect.displayStyle) {
case kWire:
sconfig->commonShader.AddDefine("GEOMETRY_OUT_WIRE");
break;
case kWireShaded:
sconfig->commonShader.AddDefine("GEOMETRY_OUT_LINE");
break;
case kShaded:
sconfig->commonShader.AddDefine("GEOMETRY_OUT_FILL");
break;
case kVaryingColor:
sconfig->commonShader.AddDefine("VARYING_COLOR");
sconfig->commonShader.AddDefine("GEOMETRY_OUT_FILL");
break;
case kInterleavedVaryingColor:
sconfig->commonShader.AddDefine("VARYING_COLOR");
sconfig->commonShader.AddDefine("GEOMETRY_OUT_FILL");
break;
case kFaceVaryingColor:
sconfig->commonShader.AddDefine("OSD_FVAR_WIDTH", "2");
sconfig->commonShader.AddDefine("FACEVARYING_COLOR");
sconfig->commonShader.AddDefine("GEOMETRY_OUT_FILL");
break;
}
return sconfig;
}
EffectDrawRegistry::ConfigType *
EffectDrawRegistry::_CreateDrawConfig(
DescType const & desc,
SourceConfigType const * sconfig)
{
ConfigType * config = BaseRegistry::_CreateDrawConfig(desc.desc, sconfig);
assert(config);
GLuint uboIndex;
// XXXdyu can use layout(binding=) with GLSL 4.20 and beyond
g_transformBinding = 0;
uboIndex = glGetUniformBlockIndex(config->program, "Transform");
if (uboIndex != GL_INVALID_INDEX)
glUniformBlockBinding(config->program, uboIndex, g_transformBinding);
g_tessellationBinding = 1;
uboIndex = glGetUniformBlockIndex(config->program, "Tessellation");
if (uboIndex != GL_INVALID_INDEX)
glUniformBlockBinding(config->program, uboIndex, g_tessellationBinding);
g_lightingBinding = 2;
uboIndex = glGetUniformBlockIndex(config->program, "Lighting");
if (uboIndex != GL_INVALID_INDEX)
glUniformBlockBinding(config->program, uboIndex, g_lightingBinding);
GLint loc;
#if not defined(GL_ARB_separate_shader_objects) || defined(GL_VERSION_4_1)
glUseProgram(config->program);
if ((loc = glGetUniformLocation(config->program, "OsdVertexBuffer")) != -1) {
glUniform1i(loc, 0); // GL_TEXTURE0
}
if ((loc = glGetUniformLocation(config->program, "OsdValenceBuffer")) != -1) {
glUniform1i(loc, 1); // GL_TEXTURE1
}
if ((loc = glGetUniformLocation(config->program, "OsdQuadOffsetBuffer")) != -1) {
glUniform1i(loc, 2); // GL_TEXTURE2
}
if ((loc = glGetUniformLocation(config->program, "OsdPatchParamBuffer")) != -1) {
glUniform1i(loc, 3); // GL_TEXTURE3
}
if ((loc = glGetUniformLocation(config->program, "OsdFVarDataBuffer")) != -1) {
glUniform1i(loc, 4); // GL_TEXTURE4
}
#else
if ((loc = glGetUniformLocation(config->program, "OsdVertexBuffer")) != -1) {
glProgramUniform1i(config->program, loc, 0); // GL_TEXTURE0
}
if ((loc = glGetUniformLocation(config->program, "OsdValenceBuffer")) != -1) {
glProgramUniform1i(config->program, loc, 1); // GL_TEXTURE1
}
if ((loc = glGetUniformLocation(config->program, "OsdQuadOffsetBuffer")) != -1) {
glProgramUniform1i(config->program, loc, 2); // GL_TEXTURE2
}
if ((loc = glGetUniformLocation(config->program, "OsdPatchParamBuffer")) != -1) {
glProgramUniform1i(config->program, loc, 3); // GL_TEXTURE3
}
if ((loc = glGetUniformLocation(config->program, "OsdFVarDataBuffer")) != -1) {
glProgramUniform1i(config->program, loc, 4); // GL_TEXTURE4
}
#endif
return config;
}
EffectDrawRegistry effectRegistry;
static Effect
GetEffect()
{
return Effect(g_displayStyle, g_screenSpaceTess, g_fractionalSpacing, g_patchCull);
}
ShaderCache g_shaderCache;
//------------------------------------------------------------------------------
static GLuint
bindProgram(Effect effect, OpenSubdiv::Osd::DrawContext::PatchArray const & patch)
{
EffectDesc effectDesc(patch.GetDescriptor(), effect);
// only legacy gregory needs maxValence and numElements
int maxValence = g_mesh->GetDrawContext()->GetMaxValence();
int numElements = (g_displayStyle == kInterleavedVaryingColor ? 7 : 3);
typedef OpenSubdiv::Far::PatchDescriptor Descriptor;
if (patch.GetDescriptor().GetType() == Descriptor::GREGORY or
patch.GetDescriptor().GetType() == Descriptor::GREGORY_BOUNDARY) {
effectDesc.maxValence = maxValence;
effectDesc.numElements = numElements;
}
EffectDrawRegistry::ConfigType *
config = effectRegistry.GetDrawConfig(effectDesc);
GLuint program = config->program;
glUseProgram(program);
static void
updateUniformBlocks() {
if (! g_transformUB) {
glGenBuffers(1, &g_transformUB);
glBindBuffer(GL_UNIFORM_BUFFER, g_transformUB);
@ -1098,7 +1078,11 @@ bindProgram(Effect effect, OpenSubdiv::Osd::DrawContext::PatchArray const & patc
glBindBuffer(GL_UNIFORM_BUFFER, 0);
glBindBufferBase(GL_UNIFORM_BUFFER, g_lightingBinding, g_lightingUB);
}
static void
bindTextures() {
// bind patch textures
if (g_mesh->GetDrawContext()->GetVertexTextureBuffer()) {
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_BUFFER,
@ -1124,10 +1108,62 @@ bindProgram(Effect effect, OpenSubdiv::Osd::DrawContext::PatchArray const & patc
glBindTexture(GL_TEXTURE_BUFFER,
g_mesh->GetDrawContext()->GetFvarDataTextureBuffer());
}
glActiveTexture(GL_TEXTURE0);
}
return program;
static GLenum
bindProgram(Effect effect,
OpenSubdiv::Osd::DrawContext::PatchArray const & patch) {
EffectDesc effectDesc(patch.GetDescriptor(), effect);
// only legacy gregory needs maxValence and numElements
typedef OpenSubdiv::Far::PatchDescriptor Descriptor;
if (patch.GetDescriptor().GetType() == Descriptor::GREGORY or
patch.GetDescriptor().GetType() == Descriptor::GREGORY_BOUNDARY) {
int maxValence = g_mesh->GetDrawContext()->GetMaxValence();
int numElements = (g_displayStyle == kInterleavedVaryingColor ? 7 : 3);
effectDesc.maxValence = maxValence;
effectDesc.numElements = numElements;
}
// lookup shader cache (compile the shader if needed)
GLDrawConfig *config = g_shaderCache.GetDrawConfig(effectDesc);
if (!config) return 0;
GLuint program = config->GetProgram();
glUseProgram(program);
// bind standalone uniforms
GLint uniformGregoryQuadOffsetBase =
glGetUniformLocation(program, "GregoryQuadOffsetBase");
GLint uniformPrimitiveIdBase =
glGetUniformLocation(program, "PrimitiveIdBase");
if (uniformGregoryQuadOffsetBase >= 0)
glUniform1i(uniformGregoryQuadOffsetBase, patch.GetQuadOffsetIndex());
if (uniformPrimitiveIdBase >=0)
glUniform1i(uniformPrimitiveIdBase, patch.GetPatchIndex());
// return primtype
GLenum primType;
switch(effectDesc.desc.GetType()) {
case Descriptor::QUADS:
primType = GL_LINES_ADJACENCY;
break;
case Descriptor::TRIANGLES:
primType = GL_TRIANGLES;
break;
default:
#if defined(GL_ARB_tessellation_shader) || defined(GL_VERSION_4_0)
primType = GL_PATCHES;
glPatchParameteri(GL_PATCH_VERTICES, effectDesc.desc.GetNumControlVertices());
#else
primType = GL_POINTS;
#endif
break;
}
return primType;
}
//------------------------------------------------------------------------------
@ -1165,6 +1201,15 @@ display() {
if (g_displayStyle == kVaryingColor)
g_mesh->BindVaryingBuffer();
// update transform and lighting uniform blocks
updateUniformBlocks();
// also bind patch related textures
bindTextures();
if (g_displayStyle == kWire)
glDisable(GL_CULL_FACE);
glEnable(GL_DEPTH_TEST);
glBindVertexArray(g_vao);
@ -1184,6 +1229,7 @@ display() {
glBeginQuery(GL_TIME_ELAPSED, g_queries[1]);
#endif
// core draw-calls
for (int i=0; i<(int)patches.size(); ++i) {
OpenSubdiv::Osd::DrawContext::PatchArray const & patch = patches[i];
@ -1193,63 +1239,11 @@ display() {
patchCount[patchType] += patch.GetNumPatches();
numTotalPatches += patch.GetNumPatches();
GLenum primType;
switch(patchType) {
case OpenSubdiv::Far::PatchDescriptor::QUADS:
primType = GL_LINES_ADJACENCY;
break;
case OpenSubdiv::Far::PatchDescriptor::TRIANGLES:
primType = GL_TRIANGLES;
break;
default:
#if defined(GL_ARB_tessellation_shader) || defined(GL_VERSION_4_0)
primType = GL_PATCHES;
glPatchParameteri(GL_PATCH_VERTICES, desc.GetNumControlVertices());
#else
primType = GL_POINTS;
#endif
}
#if defined(GL_ARB_tessellation_shader) || defined(GL_VERSION_4_0)
GLuint program = bindProgram(GetEffect(), patch);
GLuint diffuseColor = glGetUniformLocation(program, "diffuseColor");
if (g_displayPatchColor and primType == GL_PATCHES) {
float const * color = getAdaptivePatchColor( desc );
glProgramUniform4f(program, diffuseColor, color[0], color[1], color[2], color[3]);
} else {
glProgramUniform4f(program, diffuseColor, 0.4f, 0.4f, 0.8f, 1);
}
GLuint uniformGregoryQuadOffsetBase =
glGetUniformLocation(program, "GregoryQuadOffsetBase");
GLuint uniformPrimitiveIdBase =
glGetUniformLocation(program, "PrimitiveIdBase");
glProgramUniform1i(program, uniformGregoryQuadOffsetBase,
patch.GetQuadOffsetIndex());
glProgramUniform1i(program, uniformPrimitiveIdBase,
patch.GetPatchIndex());
#else
GLuint program = bindProgram(GetEffect(), patch);
GLint uniformPrimitiveIdBase =
glGetUniformLocation(program, "PrimitiveIdBase");
if (uniformPrimitiveIdBase != -1)
glUniform1i(uniformPrimitiveIdBase, patch.GetPatchIndex());
#endif
if (g_displayStyle == kWire) {
glDisable(GL_CULL_FACE);
}
GLenum primType = bindProgram(GetEffect(), patch);
glDrawElements(primType, patch.GetNumIndices(), GL_UNSIGNED_INT,
(void *)(patch.GetVertIndex() * sizeof(unsigned int)));
++numDrawCalls;
if (g_displayStyle == kWire) {
glEnable(GL_CULL_FACE);
}
}
s.Stop();
@ -1264,6 +1258,9 @@ display() {
glUseProgram(0);
if (g_displayStyle == kWire)
glEnable(GL_CULL_FACE);
if (g_drawCageEdges)
drawCageEdges();

View File

@ -31,7 +31,6 @@ set(CPU_SOURCE_FILES
cpuKernel.cpp
cpuVertexBuffer.cpp
drawContext.cpp
drawRegistry.cpp
)
set(GPU_SOURCE_FILES )
@ -50,7 +49,6 @@ set(PUBLIC_HEADER_FILES
nonCopyable.h
opengl.h
drawContext.h
drawRegistry.h
vertexDescriptor.h
)
@ -109,17 +107,17 @@ list(APPEND DOXY_HEADER_FILES ${TBB_PUBLIC_HEADERS})
set(GL_PUBLIC_HEADERS
cpuGLVertexBuffer.h
glDrawContext.h
glDrawRegistry.h
glVertexBuffer.h
glMesh.h
glslPatchShaderSource.h
)
if( OPENGL_FOUND OR OPENGLES_FOUND )
list(APPEND GPU_SOURCE_FILES
cpuGLVertexBuffer.cpp
glDrawContext.cpp
glDrawRegistry.cpp
glVertexBuffer.cpp
glslPatchShaderSource.cpp
)
list(APPEND PUBLIC_HEADER_FILES ${GL_PUBLIC_HEADERS})
if ( OPENGL_FOUND )
@ -185,17 +183,17 @@ set(DXSDK_PUBLIC_HEADERS
cpuD3D11VertexBuffer.h
d3d11ComputeEvaluator.h
d3d11DrawContext.h
d3d11DrawRegistry.h
d3d11VertexBuffer.h
d3d11Mesh.h
hlslPatchShaderSource.h
)
if( DXSDK_FOUND )
list(APPEND GPU_SOURCE_FILES
cpuD3D11VertexBuffer.cpp
d3d11ComputeEvaluator.cpp
d3d11DrawContext.cpp
d3d11DrawRegistry.cpp
d3d11VertexBuffer.cpp
hlslPatchShaderSource.cpp
)
list(APPEND PUBLIC_HEADER_FILES ${DXSDK_PUBLIC_HEADERS})
list(APPEND KERNEL_FILES

View File

@ -1,262 +0,0 @@
//
// Copyright 2013 Pixar
//
// Licensed under the Apache License, Version 2.0 (the "Apache License")
// with the following modification; you may not use this file except in
// compliance with the Apache License and the following modification to it:
// Section 6. Trademarks. is deleted and replaced with:
//
// 6. Trademarks. This License does not grant permission to use the trade
// names, trademarks, service marks, or product names of the Licensor
// and its affiliates, except as required to comply with Section 4(c) of
// the License and to reproduce the content of the NOTICE file.
//
// You may obtain a copy of the Apache License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the Apache License with the above modification is
// distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the Apache License for the specific
// language governing permissions and limitations under the Apache License.
//
#include "../osd/d3d11DrawRegistry.h"
#include "../far/error.h"
#include <D3D11.h>
#include <D3Dcompiler.h>
#include <sstream>
namespace OpenSubdiv {
namespace OPENSUBDIV_VERSION {
namespace Osd {
D3D11DrawConfig::~D3D11DrawConfig()
{
if (vertexShader) vertexShader->Release();
if (hullShader) hullShader->Release();
if (domainShader) domainShader->Release();
if (geometryShader) geometryShader->Release();
if (pixelShader) pixelShader->Release();
}
static const char *commonShaderSource =
#include "hlslPatchCommon.gen.h"
;
static const char *bsplineShaderSource =
#include "hlslPatchBSpline.gen.h"
;
static const char *gregoryShaderSource =
#include "hlslPatchGregory.gen.h"
;
D3D11DrawRegistryBase::~D3D11DrawRegistryBase() {}
D3D11DrawSourceConfig *
D3D11DrawRegistryBase::_CreateDrawSourceConfig(
Far::PatchDescriptor const & desc, ID3D11Device * pd3dDevice)
{
D3D11DrawSourceConfig * sconfig = _NewDrawSourceConfig();
sconfig->commonShader.source = commonShaderSource;
switch (desc.GetType()) {
case Far::PatchDescriptor::REGULAR:
sconfig->commonShader.AddDefine("OSD_PATCH_BSPLINE");
sconfig->commonShader.AddDefine("OSD_PATCH_ENABLE_SINGLE_CREASE");
sconfig->vertexShader.source = bsplineShaderSource;
sconfig->vertexShader.target = "vs_5_0";
sconfig->vertexShader.entry = "vs_main_patches";
sconfig->hullShader.source = bsplineShaderSource;
sconfig->hullShader.target = "hs_5_0";
sconfig->hullShader.entry = "hs_main_patches";
sconfig->domainShader.source = bsplineShaderSource;
sconfig->domainShader.target = "ds_5_0";
sconfig->domainShader.entry = "ds_main_patches";
break;
case Far::PatchDescriptor::GREGORY:
sconfig->commonShader.AddDefine("OSD_PATCH_GREGORY");
sconfig->vertexShader.source = gregoryShaderSource;
sconfig->vertexShader.target = "vs_5_0";
sconfig->vertexShader.entry = "vs_main_patches";
sconfig->hullShader.source = gregoryShaderSource;
sconfig->hullShader.target = "hs_5_0";
sconfig->hullShader.entry = "hs_main_patches";
sconfig->domainShader.source = gregoryShaderSource;
sconfig->domainShader.target = "ds_5_0";
sconfig->domainShader.entry = "ds_main_patches";
break;
case Far::PatchDescriptor::GREGORY_BOUNDARY:
sconfig->commonShader.AddDefine("OSD_PATCH_GREGORY_BOUNDARY");
sconfig->vertexShader.source = gregoryShaderSource;
sconfig->vertexShader.target = "vs_5_0";
sconfig->vertexShader.entry = "vs_main_patches";
sconfig->vertexShader.AddDefine("OSD_PATCH_GREGORY_BOUNDARY");
sconfig->hullShader.source = gregoryShaderSource;
sconfig->hullShader.target = "hs_5_0";
sconfig->hullShader.entry = "hs_main_patches";
sconfig->hullShader.AddDefine("OSD_PATCH_GREGORY_BOUNDARY");
sconfig->domainShader.source = gregoryShaderSource;
sconfig->domainShader.target = "ds_5_0";
sconfig->domainShader.entry = "ds_main_patches";
sconfig->domainShader.AddDefine("OSD_PATCH_GREGORY_BOUNDARY");
break;
case Far::PatchDescriptor::GREGORY_BASIS:
// XXXdyu-patch-drawing gregory basis for d3d11
break;
default: // POINTS, LINES, QUADS, TRIANGLES
// do nothing
break;
}
return sconfig;
}
static ID3DBlob *
_CompileShader(
DrawShaderSource const & common,
DrawShaderSource const & source)
{
DWORD dwShaderFlags = D3DCOMPILE_ENABLE_STRICTNESS;
#ifdef _DEBUG
dwShaderFlags |= D3DCOMPILE_DEBUG;
#endif
ID3DBlob* pBlob = NULL;
ID3DBlob* pBlobError = NULL;
std::vector<D3D_SHADER_MACRO> shaderDefines;
for (int i=0; i<(int)common.defines.size(); ++i) {
const D3D_SHADER_MACRO def = {
common.defines[i].first.c_str(),
common.defines[i].second.c_str(),
};
shaderDefines.push_back(def);
}
for (int i=0; i<(int)source.defines.size(); ++i) {
const D3D_SHADER_MACRO def = {
source.defines[i].first.c_str(),
source.defines[i].second.c_str(),
};
shaderDefines.push_back(def);
}
const D3D_SHADER_MACRO def = { 0, 0 };
shaderDefines.push_back(def);
std::string shaderSource = common.source + source.source;
HRESULT hr = D3DCompile(shaderSource.c_str(), shaderSource.size(),
NULL, &shaderDefines[0], NULL,
source.entry.c_str(), source.target.c_str(),
dwShaderFlags, 0, &pBlob, &pBlobError);
if (FAILED(hr)) {
if ( pBlobError != NULL ) {
Far::Error(Far::FAR_RUNTIME_ERROR,
"Error compiling HLSL shader: %s\n",
(CHAR*)pBlobError->GetBufferPointer());
pBlobError->Release();
return NULL;
}
}
return pBlob;
}
#define SAFE_RELEASE(p) { if(p) { (p)->Release(); (p)=NULL; } }
D3D11DrawConfig*
D3D11DrawRegistryBase::_CreateDrawConfig(
DescType const & desc,
SourceConfigType const * sconfig,
ID3D11Device * pd3dDevice,
ID3D11InputLayout ** ppInputLayout,
D3D11_INPUT_ELEMENT_DESC const * pInputElementDescs,
int numInputElements)
{
assert(sconfig);
ID3DBlob * pBlob;
ID3D11VertexShader *vertexShader = NULL;
if (! sconfig->vertexShader.source.empty()) {
pBlob = _CompileShader(sconfig->commonShader, sconfig->vertexShader);
pd3dDevice->CreateVertexShader(pBlob->GetBufferPointer(),
pBlob->GetBufferSize(),
NULL,
&vertexShader);
assert(vertexShader);
if (ppInputLayout and !*ppInputLayout) {
pd3dDevice->CreateInputLayout(pInputElementDescs, numInputElements,
pBlob->GetBufferPointer(),
pBlob->GetBufferSize(), ppInputLayout);
assert(ppInputLayout);
}
SAFE_RELEASE(pBlob);
}
ID3D11HullShader *hullShader = NULL;
if (! sconfig->hullShader.source.empty()) {
pBlob = _CompileShader(sconfig->commonShader, sconfig->hullShader);
pd3dDevice->CreateHullShader(pBlob->GetBufferPointer(),
pBlob->GetBufferSize(),
NULL,
&hullShader);
assert(hullShader);
SAFE_RELEASE(pBlob);
}
ID3D11DomainShader *domainShader = NULL;
if (! sconfig->domainShader.source.empty()) {
pBlob = _CompileShader(sconfig->commonShader, sconfig->domainShader);
pd3dDevice->CreateDomainShader(pBlob->GetBufferPointer(),
pBlob->GetBufferSize(),
NULL,
&domainShader);
assert(domainShader);
SAFE_RELEASE(pBlob);
}
ID3D11GeometryShader *geometryShader = NULL;
if (! sconfig->geometryShader.source.empty()) {
pBlob = _CompileShader(sconfig->commonShader, sconfig->geometryShader);
pd3dDevice->CreateGeometryShader(pBlob->GetBufferPointer(),
pBlob->GetBufferSize(),
NULL,
&geometryShader);
assert(geometryShader);
SAFE_RELEASE(pBlob);
}
ID3D11PixelShader *pixelShader = NULL;
if (! sconfig->pixelShader.source.empty()) {
pBlob = _CompileShader(sconfig->commonShader, sconfig->pixelShader);
pd3dDevice->CreatePixelShader(pBlob->GetBufferPointer(),
pBlob->GetBufferSize(),
NULL,
&pixelShader);
assert(pixelShader);
SAFE_RELEASE(pBlob);
}
D3D11DrawConfig * config = _NewDrawConfig();
config->vertexShader = vertexShader;
config->hullShader = hullShader;
config->domainShader = domainShader;
config->geometryShader = geometryShader;
config->pixelShader = pixelShader;
return config;
}
} // end namespace Osd
} // end namespace OPENSUBDIV_VERSION
} // end namespace OpenSubdiv

View File

@ -1,191 +0,0 @@
//
// Copyright 2013 Pixar
//
// Licensed under the Apache License, Version 2.0 (the "Apache License")
// with the following modification; you may not use this file except in
// compliance with the Apache License and the following modification to it:
// Section 6. Trademarks. is deleted and replaced with:
//
// 6. Trademarks. This License does not grant permission to use the trade
// names, trademarks, service marks, or product names of the Licensor
// and its affiliates, except as required to comply with Section 4(c) of
// the License and to reproduce the content of the NOTICE file.
//
// You may obtain a copy of the Apache License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the Apache License with the above modification is
// distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the Apache License for the specific
// language governing permissions and limitations under the Apache License.
//
#ifndef OSD_D3D11_DRAW_REGISTRY_H
#define OSD_D3D11_DRAW_REGISTRY_H
#include "../version.h"
#include "../far/patchTables.h"
#include "../osd/drawRegistry.h"
#include <map>
struct ID3D11VertexShader;
struct ID3D11HullShader;
struct ID3D11DomainShader;
struct ID3D11GeometryShader;
struct ID3D11PixelShader;
struct ID3D11Buffer;
struct ID3D11ShaderResourceView;
struct ID3D11Device;
struct ID3D11InputLayout;
struct D3D11_INPUT_ELEMENT_DESC;
namespace OpenSubdiv {
namespace OPENSUBDIV_VERSION {
namespace Osd {
struct D3D11DrawConfig : public DrawConfig {
D3D11DrawConfig() :
vertexShader(0), hullShader(0), domainShader(0),
geometryShader(0), pixelShader(0) {}
virtual ~D3D11DrawConfig();
ID3D11VertexShader *vertexShader;
ID3D11HullShader *hullShader;
ID3D11DomainShader *domainShader;
ID3D11GeometryShader *geometryShader;
ID3D11PixelShader *pixelShader;
};
//------------------------------------------------------------------------------
struct D3D11DrawSourceConfig {
DrawShaderSource commonShader;
DrawShaderSource vertexShader;
DrawShaderSource hullShader;
DrawShaderSource domainShader;
DrawShaderSource geometryShader;
DrawShaderSource pixelShader;
};
//------------------------------------------------------------------------------
class D3D11DrawRegistryBase {
public:
typedef Far::PatchDescriptor DescType;
typedef D3D11DrawConfig ConfigType;
typedef D3D11DrawSourceConfig SourceConfigType;
D3D11DrawRegistryBase() { }
virtual ~D3D11DrawRegistryBase();
protected:
virtual ConfigType * _NewDrawConfig() { return new ConfigType(); }
virtual ConfigType *
_CreateDrawConfig(DescType const & desc,
SourceConfigType const * sconfig,
ID3D11Device * pd3dDevice,
ID3D11InputLayout ** ppInputLayout,
D3D11_INPUT_ELEMENT_DESC const * pInputElementDescs,
int numInputElements);
virtual SourceConfigType * _NewDrawSourceConfig() { return new SourceConfigType(); }
virtual SourceConfigType *
_CreateDrawSourceConfig(DescType const & desc, ID3D11Device * pd3dDevice);
};
//------------------------------------------------------------------------------
template <class DESC_TYPE = Far::PatchDescriptor,
class CONFIG_TYPE = D3D11DrawConfig,
class SOURCE_CONFIG_TYPE = D3D11DrawSourceConfig>
class D3D11DrawRegistry : public D3D11DrawRegistryBase {
public:
typedef D3D11DrawRegistryBase BaseRegistry;
typedef DESC_TYPE DescType;
typedef CONFIG_TYPE ConfigType;
typedef SOURCE_CONFIG_TYPE SourceConfigType;
typedef std::map<DescType, ConfigType *> ConfigMap;
public:
virtual ~D3D11DrawRegistry() {
Reset();
}
void Reset() {
for (typename ConfigMap::iterator
i = _configMap.begin(); i != _configMap.end(); ++i) {
delete i->second;
}
_configMap.clear();
}
// fetch shader config
ConfigType *
GetDrawConfig(DescType const & desc,
ID3D11Device * pd3dDevice,
ID3D11InputLayout ** ppInputLayout = NULL,
D3D11_INPUT_ELEMENT_DESC const * pInputElementDescs = NULL,
int numInputElements = 0) {
typename ConfigMap::iterator it = _configMap.find(desc);
if (it != _configMap.end()) {
return it->second;
} else {
ConfigType * config =
_CreateDrawConfig(desc,
_CreateDrawSourceConfig(desc, pd3dDevice),
pd3dDevice,
ppInputLayout,
pInputElementDescs, numInputElements);
_configMap[desc] = config;
return config;
}
}
protected:
virtual ConfigType * _NewDrawConfig() {
return new ConfigType();
}
virtual ConfigType * _CreateDrawConfig(DescType const & desc,
SourceConfigType const * sconfig,
ID3D11Device * pd3dDevice,
ID3D11InputLayout ** ppInputLayout,
D3D11_INPUT_ELEMENT_DESC const * pInputElementDescs,
int numInputElements) {
return NULL;
}
virtual SourceConfigType * _NewDrawSourceConfig() {
return new SourceConfigType();
}
virtual SourceConfigType * _CreateDrawSourceConfig(DescType const & desc,
ID3D11Device * pd3dDevice) {
return NULL;
}
private:
ConfigMap _configMap;
};
} // end namespace Osd
} // end namespace OPENSUBDIV_VERSION
using namespace OPENSUBDIV_VERSION;
} // end namespace OpenSubdiv
#endif /* OSD_D3D11_DRAW_REGISTRY_H */

View File

@ -22,7 +22,6 @@
// language governing permissions and limitations under the Apache License.
//
#include "../osd/glDrawRegistry.h"
#include "../osd/glDrawContext.h"
#include "../osd/opengl.h"

View File

@ -1,257 +0,0 @@
//
// Copyright 2013 Pixar
//
// Licensed under the Apache License, Version 2.0 (the "Apache License")
// with the following modification; you may not use this file except in
// compliance with the Apache License and the following modification to it:
// Section 6. Trademarks. is deleted and replaced with:
//
// 6. Trademarks. This License does not grant permission to use the trade
// names, trademarks, service marks, or product names of the Licensor
// and its affiliates, except as required to comply with Section 4(c) of
// the License and to reproduce the content of the NOTICE file.
//
// You may obtain a copy of the Apache License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the Apache License with the above modification is
// distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the Apache License for the specific
// language governing permissions and limitations under the Apache License.
//
#include "../osd/glDrawRegistry.h"
#include "../far/error.h"
#include "../osd/opengl.h"
#include <sstream>
namespace OpenSubdiv {
namespace OPENSUBDIV_VERSION {
namespace Osd {
GLDrawConfig::~GLDrawConfig()
{
glDeleteProgram(program);
}
#if defined(GL_ARB_tessellation_shader) || defined(GL_VERSION_4_0)
static const char *commonShaderSource =
#include "glslPatchCommon.gen.h"
;
static const char *bsplineShaderSource =
#include "glslPatchBSpline.gen.h"
;
static const char *gregoryShaderSource =
#include "glslPatchGregory.gen.h"
;
static const char *gregoryBasisShaderSource =
#include "glslPatchGregoryBasis.gen.h"
;
#endif
GLDrawRegistryBase::~GLDrawRegistryBase() {}
#if defined(GL_ARB_tessellation_shader) || defined(GL_VERSION_4_0)
GLDrawSourceConfig *
GLDrawRegistryBase::_CreateDrawSourceConfig(Far::PatchDescriptor const & desc)
{
GLDrawSourceConfig * sconfig = _NewDrawSourceConfig();
sconfig->commonShader.source = commonShaderSource;
switch (desc.GetType()) {
case Far::PatchDescriptor::REGULAR:
sconfig->commonShader.AddDefine("OSD_PATCH_BSPLINE");
sconfig->commonShader.AddDefine("OSD_PATCH_ENABLE_SINGLE_CREASE");
sconfig->vertexShader.source = bsplineShaderSource;
sconfig->vertexShader.version = "#version 410\n";
sconfig->vertexShader.AddDefine("OSD_PATCH_VERTEX_BSPLINE_SHADER");
sconfig->tessControlShader.source = bsplineShaderSource;
sconfig->tessControlShader.version = "#version 410\n";
sconfig->tessControlShader.AddDefine("OSD_PATCH_TESS_CONTROL_BSPLINE_SHADER");
sconfig->tessEvalShader.source = bsplineShaderSource;
sconfig->tessEvalShader.version = "#version 410\n";
sconfig->tessEvalShader.AddDefine("OSD_PATCH_TESS_EVAL_BSPLINE_SHADER");
break;
case Far::PatchDescriptor::GREGORY:
sconfig->commonShader.AddDefine("OSD_PATCH_GREGORY");
sconfig->vertexShader.source = gregoryShaderSource;
sconfig->vertexShader.version = "#version 410\n";
sconfig->vertexShader.AddDefine("OSD_PATCH_VERTEX_GREGORY_SHADER");
sconfig->tessControlShader.source = gregoryShaderSource;
sconfig->tessControlShader.version = "#version 410\n";
sconfig->tessControlShader.AddDefine("OSD_PATCH_TESS_CONTROL_GREGORY_SHADER");
sconfig->tessEvalShader.source = gregoryShaderSource;
sconfig->tessEvalShader.version = "#version 410\n";
sconfig->tessEvalShader.AddDefine("OSD_PATCH_TESS_EVAL_GREGORY_SHADER");
break;
case Far::PatchDescriptor::GREGORY_BOUNDARY:
sconfig->commonShader.AddDefine("OSD_PATCH_GREGORY_BOUNDARY");
sconfig->vertexShader.source = gregoryShaderSource;
sconfig->vertexShader.version = "#version 410\n";
sconfig->vertexShader.AddDefine("OSD_PATCH_VERTEX_GREGORY_SHADER");
sconfig->tessControlShader.source = gregoryShaderSource;
sconfig->tessControlShader.version = "#version 410\n";
sconfig->tessControlShader.AddDefine("OSD_PATCH_TESS_CONTROL_GREGORY_SHADER");
sconfig->tessControlShader.AddDefine("OSD_PATCH_GREGORY_BOUNDARY");
sconfig->tessEvalShader.source = gregoryShaderSource;
sconfig->tessEvalShader.version = "#version 410\n";
sconfig->tessEvalShader.AddDefine("OSD_PATCH_TESS_EVAL_GREGORY_SHADER");
break;
case Far::PatchDescriptor::GREGORY_BASIS:
sconfig->commonShader.AddDefine("OSD_PATCH_GREGORY_BASIS");
sconfig->vertexShader.source = gregoryBasisShaderSource;
sconfig->vertexShader.version = "#version 410\n";
sconfig->vertexShader.AddDefine("OSD_PATCH_VERTEX_GREGORY_BASIS_SHADER");
sconfig->tessControlShader.source = gregoryBasisShaderSource;
sconfig->tessControlShader.version = "#version 410\n";
sconfig->tessControlShader.AddDefine("OSD_PATCH_TESS_CONTROL_GREGORY_BASIS_SHADER");
sconfig->tessEvalShader.source = gregoryBasisShaderSource;
sconfig->tessEvalShader.version = "#version 410\n";
sconfig->tessEvalShader.AddDefine("OSD_PATCH_TESS_EVAL_GREGORY_BASIS_SHADER");
break;
default: // POINTS, LINES, QUADS, TRIANGLES
// do nothing
break;
}
return sconfig;
}
#else
GLDrawSourceConfig *
GLDrawRegistryBase::_CreateDrawSourceConfig(Far::PatchDescriptor const &)
{
return _NewDrawSourceConfig();
}
#endif
static GLuint
_CompileShader(
GLenum shaderType,
OpenSubdiv::Osd::DrawShaderSource const & common,
OpenSubdiv::Osd::DrawShaderSource const & source)
{
const char *sources[4];
std::stringstream definitions;
for (int i=0; i<(int)common.defines.size(); ++i) {
definitions << "#define "
<< common.defines[i].first << " "
<< common.defines[i].second << "\n";
}
for (int i=0; i<(int)source.defines.size(); ++i) {
definitions << "#define "
<< source.defines[i].first << " "
<< source.defines[i].second << "\n";
}
std::string defString = definitions.str();
sources[0] = source.version.c_str();
sources[1] = defString.c_str();
sources[2] = common.source.c_str();
sources[3] = source.source.c_str();
GLuint shader = glCreateShader(shaderType);
glShaderSource(shader, 4, sources, NULL);
glCompileShader(shader);
GLint status;
glGetShaderiv(shader, GL_COMPILE_STATUS, &status);
if( status == GL_FALSE ) {
GLint infoLogLength;
glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLogLength);
char * infoLog = new char[infoLogLength];
glGetShaderInfoLog(shader, infoLogLength, NULL, infoLog);
Far::Error(Far::FAR_RUNTIME_ERROR,
"Error compiling GLSL shader: %s\nDefines: \n%s\n",
infoLog, defString.c_str());
delete[] infoLog;
}
return shader;
}
GLDrawConfig *
GLDrawRegistryBase::_CreateDrawConfig(
Far::PatchDescriptor const & /* desc */,
GLDrawSourceConfig const * sconfig)
{
assert(sconfig);
GLDrawConfig * config = _NewDrawConfig();
assert(config);
GLuint vertexShader =
sconfig->vertexShader.source.empty() ? 0 :
_CompileShader(GL_VERTEX_SHADER,
sconfig->commonShader, sconfig->vertexShader);
GLuint tessControlShader = 0;
GLuint tessEvalShader = 0;
#if defined(GL_ARB_tessellation_shader) || defined(GL_VERSION_4_0)
tessControlShader =
sconfig->tessControlShader.source.empty() ? 0 :
_CompileShader(GL_TESS_CONTROL_SHADER,
sconfig->commonShader, sconfig->tessControlShader);
tessEvalShader =
sconfig->tessEvalShader.source.empty() ? 0 :
_CompileShader(GL_TESS_EVALUATION_SHADER,
sconfig->commonShader, sconfig->tessEvalShader);
#endif
GLuint geometryShader = 0;
#if defined(GL_ARB_geometry_shader4) || defined(GL_VERSION_3_1)
geometryShader =
sconfig->geometryShader.source.empty() ? 0 :
_CompileShader(GL_GEOMETRY_SHADER,
sconfig->commonShader, sconfig->geometryShader);
#endif
GLuint fragmentShader =
sconfig->fragmentShader.source.empty() ? 0 :
_CompileShader(GL_FRAGMENT_SHADER,
sconfig->commonShader, sconfig->fragmentShader);
GLuint program = glCreateProgram();
if (vertexShader) glAttachShader(program, vertexShader);
if (tessControlShader) glAttachShader(program, tessControlShader);
if (tessEvalShader) glAttachShader(program, tessEvalShader);
if (geometryShader) glAttachShader(program, geometryShader);
if (fragmentShader) glAttachShader(program, fragmentShader);
glLinkProgram(program);
glDeleteShader(vertexShader);
glDeleteShader(tessControlShader);
glDeleteShader(tessEvalShader);
glDeleteShader(geometryShader);
glDeleteShader(fragmentShader);
GLint status;
glGetProgramiv(program, GL_LINK_STATUS, &status );
if( status == GL_FALSE ) {
GLint infoLogLength;
glGetProgramiv(program, GL_INFO_LOG_LENGTH, &infoLogLength);
char * infoLog = new char[infoLogLength];
glGetProgramInfoLog(program, infoLogLength, NULL, infoLog);
Far::Error(Far::FAR_RUNTIME_ERROR,
"Error linking GLSL program: %s\n", infoLog);
delete[] infoLog;
}
config->program = program;
return config;
}
} // end namespace Osd
} // end namespace OPENSUBDIV_VERSION
} // end namespace OpenSubdiv

View File

@ -1,161 +0,0 @@
//
// Copyright 2013 Pixar
//
// Licensed under the Apache License, Version 2.0 (the "Apache License")
// with the following modification; you may not use this file except in
// compliance with the Apache License and the following modification to it:
// Section 6. Trademarks. is deleted and replaced with:
//
// 6. Trademarks. This License does not grant permission to use the trade
// names, trademarks, service marks, or product names of the Licensor
// and its affiliates, except as required to comply with Section 4(c) of
// the License and to reproduce the content of the NOTICE file.
//
// You may obtain a copy of the Apache License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the Apache License with the above modification is
// distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the Apache License for the specific
// language governing permissions and limitations under the Apache License.
//
#ifndef OSD_GL_DRAW_REGISTRY_H
#define OSD_GL_DRAW_REGISTRY_H
#include "../version.h"
#include "../osd/drawRegistry.h"
#include "../osd/opengl.h"
#include <map>
namespace OpenSubdiv {
namespace OPENSUBDIV_VERSION {
namespace Osd {
struct GLDrawConfig : public DrawConfig {
GLDrawConfig() :
program(0) { }
virtual ~GLDrawConfig();
GLuint program;
};
//------------------------------------------------------------------------------
struct GLDrawSourceConfig : public DrawSourceConfig {
DrawShaderSource commonShader;
DrawShaderSource vertexShader;
DrawShaderSource tessControlShader;
DrawShaderSource tessEvalShader;
DrawShaderSource geometryShader;
DrawShaderSource fragmentShader;
};
//------------------------------------------------------------------------------
class GLDrawRegistryBase {
public:
typedef Far::PatchDescriptor DescType;
typedef GLDrawConfig ConfigType;
typedef GLDrawSourceConfig SourceConfigType;
GLDrawRegistryBase() { }
virtual ~GLDrawRegistryBase();
protected:
virtual ConfigType * _NewDrawConfig() {
return new ConfigType();
}
virtual ConfigType * _CreateDrawConfig(DescType const & desc,
SourceConfigType const * sconfig);
virtual SourceConfigType * _NewDrawSourceConfig() {
return new SourceConfigType();
}
virtual SourceConfigType * _CreateDrawSourceConfig(DescType const & desc);
};
//------------------------------------------------------------------------------
template <class DESC_TYPE = Far::PatchDescriptor,
class CONFIG_TYPE = GLDrawConfig,
class SOURCE_CONFIG_TYPE = GLDrawSourceConfig >
class GLDrawRegistry : public GLDrawRegistryBase {
public:
typedef DESC_TYPE DescType;
typedef CONFIG_TYPE ConfigType;
typedef SOURCE_CONFIG_TYPE SourceConfigType;
typedef GLDrawRegistryBase BaseRegistry;
typedef std::map<DescType, ConfigType *> ConfigMap;
virtual ~GLDrawRegistry() {
Reset();
}
void Reset() {
for (typename ConfigMap::iterator
i = _configMap.begin(); i != _configMap.end(); ++i) {
delete i->second;
}
_configMap.clear();
}
// fetch shader config
ConfigType * GetDrawConfig(DescType const & desc) {
typename ConfigMap::iterator it = _configMap.find(desc);
if (it != _configMap.end()) {
return it->second;
} else {
ConfigType * config =
_CreateDrawConfig(desc, _CreateDrawSourceConfig(desc));
_configMap[desc] = config;
return config;
}
}
protected:
virtual ConfigType * _NewDrawConfig() {
return new ConfigType();
}
virtual ConfigType * _CreateDrawConfig(DescType const & /* desc */,
SourceConfigType const * /* sconfig */) {
return NULL;
}
virtual SourceConfigType * _NewDrawSourceConfig() {
return new SourceConfigType();
}
virtual SourceConfigType * _CreateDrawSourceConfig(DescType const & /* desc */) {
return NULL;
}
private:
ConfigMap _configMap;
};
} // end namespace Osd
} // end namespace OPENSUBDIV_VERSION
using namespace OPENSUBDIV_VERSION;
} // end namespace OpenSubdiv
#endif /* OSD_GL_DRAW_REGISTRY_H */

View File

@ -0,0 +1,151 @@
//
// Copyright 2015 Pixar
//
// Licensed under the Apache License, Version 2.0 (the "Apache License")
// with the following modification; you may not use this file except in
// compliance with the Apache License and the following modification to it:
// Section 6. Trademarks. is deleted and replaced with:
//
// 6. Trademarks. This License does not grant permission to use the trade
// names, trademarks, service marks, or product names of the Licensor
// and its affiliates, except as required to comply with Section 4(c) of
// the License and to reproduce the content of the NOTICE file.
//
// You may obtain a copy of the Apache License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the Apache License with the above modification is
// distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the Apache License for the specific
// language governing permissions and limitations under the Apache License.
//
#include "../osd/glslPatchShaderSource.h"
#include <sstream>
#include <string>
namespace OpenSubdiv {
namespace OPENSUBDIV_VERSION {
namespace Osd {
static const char *commonShaderSource =
#include "glslPatchCommon.gen.h"
;
static const char *bsplineShaderSource =
#include "glslPatchBSpline.gen.h"
;
static const char *gregoryShaderSource =
#include "glslPatchGregory.gen.h"
;
static const char *gregoryBasisShaderSource =
#include "glslPatchGregoryBasis.gen.h"
;
/*static*/
std::string
GLSLPatchShaderSource::GetCommonShaderSource() {
return std::string(commonShaderSource);
}
/*static*/
std::string
GLSLPatchShaderSource::GetVertexShaderSource(Far::PatchDescriptor::Type type) {
std::stringstream ss;
switch (type) {
case Far::PatchDescriptor::REGULAR:
ss << "#define OSD_PATCH_BSPLINE\n"
<< "#define OSD_PATCH_VERTEX_BSPLINE_SHADER\n"
<< bsplineShaderSource;
break;
case Far::PatchDescriptor::GREGORY:
ss << "#define OSD_PATCH_GREGORY\n"
<< "#define OSD_PATCH_VERTEX_GREGORY_SHADER\n"
<< gregoryShaderSource;
break;
case Far::PatchDescriptor::GREGORY_BOUNDARY:
ss << "#define OSD_PATCH_GREGORY_BOUNDARY\n"
<< "#define OSD_PATCH_VERTEX_GREGORY_SHADER\n"
<< gregoryShaderSource;
break;
case Far::PatchDescriptor::GREGORY_BASIS:
ss << "#define OSD_PATCH_GREGORY_BASIS\n"
<< "#define OSD_PATCH_VERTEX_GREGORY_BASIS_SHADER\n"
<< gregoryBasisShaderSource;
break;
default:
break; // returns empty (points, lines, quads, ...)
}
return ss.str();
}
/*static*/
std::string
GLSLPatchShaderSource::GetTessControlShaderSource(
Far::PatchDescriptor::Type type) {
std::stringstream ss;
switch (type) {
case Far::PatchDescriptor::REGULAR:
ss << "#define OSD_PATCH_BSPLINE\n"
<< "#define OSD_PATCH_TESS_CONTROL_BSPLINE_SHADER\n"
<< bsplineShaderSource;
break;
case Far::PatchDescriptor::GREGORY:
ss << "#define OSD_PATCH_GREGORY\n"
<< "#define OSD_PATCH_TESS_CONTROL_GREGORY_SHADER\n"
<< gregoryShaderSource;
break;
case Far::PatchDescriptor::GREGORY_BOUNDARY:
ss << "#define OSD_PATCH_GREGORY_BOUNDARY\n"
<< "#define OSD_PATCH_TESS_CONTROL_GREGORY_SHADER\n"
<< gregoryShaderSource;
break;
case Far::PatchDescriptor::GREGORY_BASIS:
ss << "#define OSD_PATCH_GREGORY_BASIS\n"
<< "#define OSD_PATCH_TESS_CONTROL_GREGORY_BASIS_SHADER\n"
<< gregoryBasisShaderSource;
break;
default:
break; // returns empty (points, lines, quads, ...)
}
return ss.str();
}
/*static*/
std::string
GLSLPatchShaderSource::GetTessEvalShaderSource(
Far::PatchDescriptor::Type type) {
std::stringstream ss;
switch (type) {
case Far::PatchDescriptor::REGULAR:
ss << "#define OSD_PATCH_BSPLINE\n"
<< "#define OSD_PATCH_TESS_EVAL_BSPLINE_SHADER\n"
<< bsplineShaderSource;
break;
case Far::PatchDescriptor::GREGORY:
ss << "#define OSD_PATCH_GREGORY\n"
<< "#define OSD_PATCH_TESS_EVAL_GREGORY_SHADER\n"
<< gregoryShaderSource;
break;
case Far::PatchDescriptor::GREGORY_BOUNDARY:
ss << "#define OSD_PATCH_GREGORY_BOUNDARY\n"
<< "#define OSD_PATCH_TESS_EVAL_GREGORY_SHADER\n"
<< gregoryShaderSource;
break;
case Far::PatchDescriptor::GREGORY_BASIS:
ss << "#define OSD_PATCH_GREGORY_BASIS\n"
<< "#define OSD_PATCH_TESS_EVAL_GREGORY_BASIS_SHADER\n"
<< gregoryBasisShaderSource;
break;
default:
break; // returns empty (points, lines, quads, ...)
}
return ss.str();
}
} // end namespace Osd
} // end namespace OPENSUBDIV_VERSION
} // end namespace OpenSubdiv

View File

@ -1,5 +1,5 @@
//
// Copyright 2013 Pixar
// Copyright 2015 Pixar
//
// Licensed under the Apache License, Version 2.0 (the "Apache License")
// with the following modification; you may not use this file except in
@ -22,51 +22,32 @@
// language governing permissions and limitations under the Apache License.
//
#ifndef OSD_DRAW_REGISTRY_H
#define OSD_DRAW_REGISTRY_H
#ifndef OPENSUBDIV_OSD_GLSL_PATCH_SHADER_SOURCE_H
#define OPENSUBDIV_OSD_GLSL_PATCH_SHADER_SOURCE_H
#include "../version.h"
#include "../osd/drawContext.h"
#include <utility>
#include <string>
#include <vector>
#include "../far/patchDescriptor.h"
namespace OpenSubdiv {
namespace OPENSUBDIV_VERSION {
namespace Osd {
struct DrawShaderSource {
typedef std::pair< std::string, std::string > Define;
typedef std::vector< Define > DefineVector;
class GLSLPatchShaderSource {
public:
static std::string GetCommonShaderSource();
void AddDefine(std::string const & name,
std::string const & value = "1") {
defines.push_back( Define(name, value) );
}
static std::string GetVertexShaderSource(
Far::PatchDescriptor::Type type);
std::string source;
std::string version;
std::string target;
std::string entry;
static std::string GetTessControlShaderSource(
Far::PatchDescriptor::Type type);
DefineVector defines;
static std::string GetTessEvalShaderSource(
Far::PatchDescriptor::Type type);
};
struct DrawConfig {
virtual ~DrawConfig();
// any base class behaviors?
};
struct DrawSourceConfig {
virtual ~DrawSourceConfig();
// any base class behaviors?
};
////////////////////////////////////////////////////////////
} // end namespace Osd
} // end namespace OPENSUBDIV_VERSION
@ -74,4 +55,4 @@ using namespace OPENSUBDIV_VERSION;
} // end namespace OpenSubdiv
#endif /* OSD_DRAW_REGISTRY_H */
#endif // OPENSUBDIV_OSD_GLSL_PATCH_SHADER_SOURCE

View File

@ -0,0 +1,115 @@
//
// Copyright 2015 Pixar
//
// Licensed under the Apache License, Version 2.0 (the "Apache License")
// with the following modification; you may not use this file except in
// compliance with the Apache License and the following modification to it:
// Section 6. Trademarks. is deleted and replaced with:
//
// 6. Trademarks. This License does not grant permission to use the trade
// names, trademarks, service marks, or product names of the Licensor
// and its affiliates, except as required to comply with Section 4(c) of
// the License and to reproduce the content of the NOTICE file.
//
// You may obtain a copy of the Apache License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the Apache License with the above modification is
// distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the Apache License for the specific
// language governing permissions and limitations under the Apache License.
//
#include "../osd/hlslPatchShaderSource.h"
#include "../far/error.h"
#include <sstream>
#include <string>
namespace OpenSubdiv {
namespace OPENSUBDIV_VERSION {
namespace Osd {
static const char *commonShaderSource =
#include "hlslPatchCommon.gen.h"
;
static const char *bsplineShaderSource =
#include "hlslPatchBSpline.gen.h"
;
static const char *gregoryShaderSource =
#include "hlslPatchGregory.gen.h"
;
/*static*/
std::string
HLSLPatchShaderSource::GetCommonShaderSource() {
return std::string(commonShaderSource);
}
/*static*/
std::string
HLSLPatchShaderSource::GetVertexShaderSource(Far::PatchDescriptor::Type type) {
switch (type) {
case Far::PatchDescriptor::REGULAR:
return bsplineShaderSource;
case Far::PatchDescriptor::GREGORY:
return gregoryShaderSource;
case Far::PatchDescriptor::GREGORY_BOUNDARY:
return std::string("#define OSD_PATCH_GREGORY_BOUNDRY\n")
+ std::string(gregoryShaderSource);
case Far::PatchDescriptor::GREGORY_BASIS:
assert(false); // not implemented yet.
break;
default:
break; // returns empty (points, lines, quads, ...)
}
return std::string();
}
/*static*/
std::string
HLSLPatchShaderSource::GetHullShaderSource(Far::PatchDescriptor::Type type) {
switch (type) {
case Far::PatchDescriptor::REGULAR:
return bsplineShaderSource;
case Far::PatchDescriptor::GREGORY:
return gregoryShaderSource;
case Far::PatchDescriptor::GREGORY_BOUNDARY:
return std::string("#define OSD_PATCH_GREGORY_BOUNDRY\n")
+ std::string(gregoryShaderSource);
case Far::PatchDescriptor::GREGORY_BASIS:
assert(false); // not implemented yet.
break;
default:
break; // returns empty (points, lines, quads, ...)
}
return std::string();
}
/*static*/
std::string
HLSLPatchShaderSource::GetDomainShaderSource(Far::PatchDescriptor::Type type) {
switch (type) {
case Far::PatchDescriptor::REGULAR:
return bsplineShaderSource;
case Far::PatchDescriptor::GREGORY:
return gregoryShaderSource;
case Far::PatchDescriptor::GREGORY_BOUNDARY:
return std::string("#define OSD_PATCH_GREGORY_BOUNDRY\n")
+ std::string(gregoryShaderSource);
case Far::PatchDescriptor::GREGORY_BASIS:
assert(false); // not implemented yet.
break;
default:
break; // returns empty (points, lines, quads, ...)
}
return std::string();
}
} // end namespace Osd
} // end namespace OPENSUBDIV_VERSION
} // end namespace OpenSubdiv

View File

@ -1,5 +1,5 @@
//
// Copyright 2013 Pixar
// Copyright 2015 Pixar
//
// Licensed under the Apache License, Version 2.0 (the "Apache License")
// with the following modification; you may not use this file except in
@ -22,17 +22,34 @@
// language governing permissions and limitations under the Apache License.
//
#include "../osd/drawRegistry.h"
#ifndef OPENSUBDIV_OSD_HLSL_PATCH_SHADER_SOURCE_H
#define OPENSUBDIV_OSD_HLSL_PATCH_SHADER_SOURCE_H
#include "../version.h"
#include <string>
#include "../far/patchDescriptor.h"
namespace OpenSubdiv {
namespace OPENSUBDIV_VERSION {
namespace Osd {
DrawConfig::~DrawConfig() {}
DrawSourceConfig::~DrawSourceConfig() {}
class HLSLPatchShaderSource {
public:
static std::string GetCommonShaderSource();
static std::string GetVertexShaderSource(Far::PatchDescriptor::Type type);
static std::string GetHullShaderSource(Far::PatchDescriptor::Type type);
static std::string GetDomainShaderSource(Far::PatchDescriptor::Type type);
};
} // end namespace Osd
} // end namespace OPENSUBDIV_VERSION
using namespace OPENSUBDIV_VERSION;
} // end namespace OpenSubdiv
#endif // OPENSUBDIV_OSD_HLSL_PATCH_SHADER_SOURCE_H