Merge pull request #474 from takahito-tejima/refactor2

Osd drawing API refactoring.
This commit is contained in:
David G Yu 2015-05-14 10:05:35 -07:00
commit c5b7224b77
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