mirror of
https://github.com/PixarAnimationStudios/OpenSubdiv
synced 2025-01-13 09:50:09 +00:00
Merge pull request #474 from takahito-tejima/refactor2
Osd drawing API refactoring.
This commit is contained in:
commit
c5b7224b77
@ -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