mirror of
https://github.com/PixarAnimationStudios/OpenSubdiv
synced 2024-09-19 14:20:00 +00:00
Osd drawing API refactoring.
Remove DrawRegistry from osd layer and put a simple shader caching utility into examples/common. osd layer only provides patch shader snippet and let client configure and compile the code. Clients also maintain the lifetime of shader object, which is preferable for the actual application integration. update all examples to use the new scheme.
This commit is contained in:
parent
a0e3b59ae5
commit
4a4322983f
@ -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}")
|
||||
|
186
examples/common/d3d11ShaderCache.cpp
Normal file
186
examples/common/d3d11ShaderCache.cpp
Normal 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;
|
||||
}
|
||||
|
93
examples/common/d3d11ShaderCache.h
Normal file
93
examples/common/d3d11ShaderCache.h
Normal 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
|
98
examples/common/glShaderCache.cpp
Normal file
98
examples/common/glShaderCache.cpp
Normal 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;
|
||||
}
|
62
examples/common/glShaderCache.h
Normal file
62
examples/common/glShaderCache.h
Normal 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
|
70
examples/common/shaderCache.h
Normal file
70
examples/common/shaderCache.h
Normal 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
|
@ -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());
|
||||
|
@ -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
|
||||
|
@ -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');
|
||||
|
@ -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
|
||||
|
@ -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();
|
||||
|
@ -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
|
||||
|
@ -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,
|
||||
|
@ -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
@ -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
|
@ -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];
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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};
|
||||
|
@ -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();
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
@ -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 */
|
@ -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"
|
||||
|
@ -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
|
@ -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 */
|
151
opensubdiv/osd/glslPatchShaderSource.cpp
Normal file
151
opensubdiv/osd/glslPatchShaderSource.cpp
Normal 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
|
@ -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
|
115
opensubdiv/osd/hlslPatchShaderSource.cpp
Normal file
115
opensubdiv/osd/hlslPatchShaderSource.cpp
Normal 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
|
@ -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
|
Loading…
Reference in New Issue
Block a user