mirror of
https://github.com/PixarAnimationStudios/OpenSubdiv
synced 2024-09-19 14:20:00 +00:00
Examples cleanup: factor out control mesh drawing.
- add GLControlMeshDisplay and D3D11ControlMeshDisplay into examples/common - delete all drawCageEdges/drawCageVertices from viewers and use ControlMeshDisplay class
This commit is contained in:
parent
39e22e55b2
commit
7394bf5f51
@ -52,6 +52,7 @@ 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
|
||||
glControlMeshDisplay.cpp
|
||||
glFramebuffer.cpp
|
||||
glHud.cpp
|
||||
glUtils.cpp
|
||||
@ -59,6 +60,7 @@ if( OPENGL_FOUND AND (GLEW_FOUND AND GLFW_FOUND) OR (APPLE AND GLFW_FOUND))
|
||||
)
|
||||
|
||||
list(APPEND EXAMPLES_COMMON_HEADER_FILES
|
||||
glControlMeshDisplay.h
|
||||
glFramebuffer.h
|
||||
glHud.h
|
||||
glUtils.h
|
||||
@ -83,12 +85,14 @@ endif()
|
||||
if(DXSDK_FOUND)
|
||||
|
||||
list(APPEND EXAMPLES_COMMON_SOURCE_FILES
|
||||
d3d11ControlMeshDisplay.cpp
|
||||
d3d11Hud.cpp
|
||||
d3d11Utils.cpp
|
||||
d3d11ShaderCache.cpp
|
||||
)
|
||||
|
||||
list(APPEND EXAMPLES_COMMON_HEADER_FILES
|
||||
d3d11ControlMeshDisplay.h
|
||||
d3d11Hud.h
|
||||
d3d11Utils.h
|
||||
d3d11ShaderCache.h
|
||||
|
268
examples/common/d3d11ControlMeshDisplay.cpp
Normal file
268
examples/common/d3d11ControlMeshDisplay.cpp
Normal file
@ -0,0 +1,268 @@
|
||||
//
|
||||
// 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 "d3d11ControlMeshDisplay.h"
|
||||
#include "../common/d3d11Utils.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
#define SAFE_RELEASE(p) { if(p) { (p)->Release(); (p)=NULL; } }
|
||||
|
||||
static const char *s_VS =
|
||||
"cbuffer cbPerFrame : register( b0 ) { matrix g_mViewProjection; }; \n"
|
||||
"struct vertexIn { float3 pos : POSITION0; float sharpness : COLOR0; }; \n"
|
||||
"struct vertexOut { float4 pos : SV_POSITION; float sharpness : COLOR0; }; \n"
|
||||
"vertexOut vs_main(vertexIn IN) { \n"
|
||||
" vertexOut vout; \n"
|
||||
" vout.pos = mul(g_mViewProjection, float4(IN.pos, 1)); \n"
|
||||
" vout.sharpness = IN.sharpness; \n"
|
||||
" return vout; \n"
|
||||
"} \n";
|
||||
|
||||
static const char *s_PS =
|
||||
"struct pixelIn { float4 pos : SV_POSITION; float sharpness : COLOR0; }; \n"
|
||||
"Buffer<float> edgeSharpness : register(t0); \n"
|
||||
"float4 sharpnessToColor(float s) { \n"
|
||||
" // 0.0 2.0 4.0 \n"
|
||||
" // green --- yellow --- red \n"
|
||||
" return float4(min(1, s * 0.5), \n"
|
||||
" min(1, 2 - s * 0.5), \n"
|
||||
" 0, 1); \n"
|
||||
"} \n"
|
||||
"float4 ps_main(pixelIn IN, uint primitiveID : SV_PrimitiveID) \n"
|
||||
" : SV_Target { \n"
|
||||
" float sharpness = edgeSharpness[primitiveID]; \n"
|
||||
" return sharpnessToColor(sharpness); \n"
|
||||
"} \n";
|
||||
|
||||
namespace {
|
||||
struct CB_CONTROL_MESH_DISPLAY
|
||||
{
|
||||
float mViewProjection[16];
|
||||
};
|
||||
};
|
||||
|
||||
D3D11ControlMeshDisplay::D3D11ControlMeshDisplay(
|
||||
ID3D11DeviceContext *deviceContext) :
|
||||
_displayEdges(true), _displayVertices(false),
|
||||
_deviceContext(deviceContext), _inputLayout(0), _vertexShader(0),
|
||||
_pixelShader(0), _rasterizerState(0), _constantBuffer(0),
|
||||
_edgeSharpnessSRV(0), _edgeSharpness(0), _edgeIndices(0),
|
||||
_numEdges(0), _numPoints(0) {
|
||||
}
|
||||
|
||||
D3D11ControlMeshDisplay::~D3D11ControlMeshDisplay() {
|
||||
SAFE_RELEASE(_inputLayout);
|
||||
SAFE_RELEASE(_vertexShader);
|
||||
SAFE_RELEASE(_pixelShader);
|
||||
SAFE_RELEASE(_rasterizerState);
|
||||
SAFE_RELEASE(_constantBuffer);
|
||||
SAFE_RELEASE(_edgeSharpness);
|
||||
SAFE_RELEASE(_edgeSharpnessSRV);
|
||||
SAFE_RELEASE(_edgeIndices);
|
||||
}
|
||||
|
||||
bool
|
||||
D3D11ControlMeshDisplay::createProgram() {
|
||||
ID3D11Device *device = NULL;
|
||||
_deviceContext->GetDevice(&device);
|
||||
|
||||
ID3DBlob* pVSBlob;
|
||||
ID3DBlob* pPSBlob;
|
||||
pVSBlob = D3D11Utils::CompileShader(s_VS, "vs_main", "vs_4_0");
|
||||
pPSBlob = D3D11Utils::CompileShader(s_PS, "ps_main", "ps_4_0");
|
||||
assert(pVSBlob);
|
||||
assert(pPSBlob);
|
||||
|
||||
D3D11_INPUT_ELEMENT_DESC inputElementDesc[] = {
|
||||
{ "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0,
|
||||
D3D11_INPUT_PER_VERTEX_DATA, 0 },
|
||||
{ "COLOR", 0, DXGI_FORMAT_R32_FLOAT, 0, sizeof(float)*3,
|
||||
D3D11_INPUT_PER_VERTEX_DATA, 0 },
|
||||
};
|
||||
device->CreateInputLayout(inputElementDesc, ARRAYSIZE(inputElementDesc),
|
||||
pVSBlob->GetBufferPointer(),
|
||||
pVSBlob->GetBufferSize(),
|
||||
&_inputLayout);
|
||||
assert(_inputLayout);
|
||||
|
||||
device->CreateVertexShader(pVSBlob->GetBufferPointer(),
|
||||
pVSBlob->GetBufferSize(),
|
||||
NULL, &_vertexShader);
|
||||
assert(_vertexShader);
|
||||
|
||||
device->CreatePixelShader(pPSBlob->GetBufferPointer(),
|
||||
pPSBlob->GetBufferSize(),
|
||||
NULL, &_pixelShader);
|
||||
assert(_pixelShader);
|
||||
|
||||
D3D11_RASTERIZER_DESC rasDesc;
|
||||
rasDesc.FillMode = D3D11_FILL_SOLID;
|
||||
rasDesc.CullMode = D3D11_CULL_NONE;
|
||||
rasDesc.FrontCounterClockwise = FALSE;
|
||||
rasDesc.DepthBias = 0;
|
||||
rasDesc.DepthBiasClamp = 0;
|
||||
rasDesc.SlopeScaledDepthBias = 0.0f;
|
||||
rasDesc.DepthClipEnable = FALSE;
|
||||
rasDesc.ScissorEnable = FALSE;
|
||||
rasDesc.MultisampleEnable = FALSE;
|
||||
rasDesc.AntialiasedLineEnable = FALSE;
|
||||
device->CreateRasterizerState(&rasDesc, &_rasterizerState);
|
||||
assert(_rasterizerState);
|
||||
|
||||
// constant buffer
|
||||
D3D11_BUFFER_DESC cbDesc;
|
||||
cbDesc.Usage = D3D11_USAGE_DYNAMIC;
|
||||
cbDesc.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
|
||||
cbDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
|
||||
cbDesc.MiscFlags = 0;
|
||||
cbDesc.ByteWidth = sizeof(CB_CONTROL_MESH_DISPLAY);
|
||||
|
||||
device->CreateBuffer(&cbDesc, NULL, &_constantBuffer);
|
||||
assert(_constantBuffer);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
D3D11ControlMeshDisplay::Draw(ID3D11Buffer *buffer, int stride,
|
||||
const float *modelViewProjectionMatrix) {
|
||||
|
||||
if (_displayEdges == false && _displayVertices == false) return;
|
||||
|
||||
if (_vertexShader == NULL) createProgram();
|
||||
if (_vertexShader == NULL) return;
|
||||
|
||||
UINT hStrides = stride*sizeof(float);
|
||||
UINT hOffsets = 0;
|
||||
_deviceContext->IASetVertexBuffers(0, 1, &buffer, &hStrides, &hOffsets);
|
||||
|
||||
D3D11_MAPPED_SUBRESOURCE MappedResource;
|
||||
_deviceContext->Map(_constantBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &MappedResource);
|
||||
CB_CONTROL_MESH_DISPLAY * pData = (CB_CONTROL_MESH_DISPLAY *)MappedResource.pData;
|
||||
memcpy(pData->mViewProjection, modelViewProjectionMatrix, sizeof(float) * 16);
|
||||
_deviceContext->Unmap(_constantBuffer, 0);
|
||||
|
||||
_deviceContext->IASetInputLayout(_inputLayout);
|
||||
_deviceContext->VSSetShader(_vertexShader, NULL, 0);
|
||||
_deviceContext->HSSetShader(NULL, NULL, 0);
|
||||
_deviceContext->DSSetShader(NULL, NULL, 0);
|
||||
_deviceContext->GSSetShader(NULL, NULL, 0);
|
||||
_deviceContext->PSSetShaderResources(0, 1, &_edgeSharpnessSRV);
|
||||
_deviceContext->PSSetShader(_pixelShader, NULL, 0);
|
||||
_deviceContext->RSSetState(_rasterizerState);
|
||||
_deviceContext->VSSetConstantBuffers(0, 1, &_constantBuffer);
|
||||
|
||||
if (_displayEdges) {
|
||||
_deviceContext->IASetIndexBuffer(_edgeIndices, DXGI_FORMAT_R32_UINT, 0);
|
||||
_deviceContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_LINELIST);
|
||||
_deviceContext->DrawIndexed(_numEdges * 2, 0, 0);
|
||||
}
|
||||
if (_displayVertices) {
|
||||
// TODO: need geometry shader to draw bigger points
|
||||
_deviceContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_POINTLIST);
|
||||
_deviceContext->Draw(_numPoints, 0);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
D3D11ControlMeshDisplay::SetTopology(
|
||||
OpenSubdiv::Far::TopologyLevel const &level) {
|
||||
int nEdges = level.GetNumEdges();
|
||||
int nVerts = level.GetNumVertices();
|
||||
|
||||
std::vector<int> edgeIndices;
|
||||
std::vector<float> edgeSharpnesses;
|
||||
std::vector<float> vertSharpnesses;
|
||||
|
||||
edgeIndices.reserve(nEdges * 2);
|
||||
edgeSharpnesses.reserve(nEdges);
|
||||
vertSharpnesses.reserve(nVerts);
|
||||
|
||||
for (int i = 0; i < nEdges; ++i) {
|
||||
OpenSubdiv::Far::ConstIndexArray verts = level.GetEdgeVertices(i);
|
||||
edgeIndices.push_back(verts[0]);
|
||||
edgeIndices.push_back(verts[1]);
|
||||
edgeSharpnesses.push_back(level.GetEdgeSharpness(i));
|
||||
}
|
||||
|
||||
for (int i = 0; i < nVerts; ++i) {
|
||||
vertSharpnesses.push_back(level.GetVertexSharpness(i));
|
||||
}
|
||||
|
||||
_numEdges = nEdges;
|
||||
_numPoints = nVerts;
|
||||
|
||||
ID3D11Device *device = NULL;
|
||||
_deviceContext->GetDevice(&device);
|
||||
|
||||
SAFE_RELEASE(_edgeIndices);
|
||||
// create edge index buffer
|
||||
D3D11_BUFFER_DESC bufferDesc;
|
||||
ZeroMemory(&bufferDesc, sizeof(bufferDesc));
|
||||
bufferDesc.ByteWidth = (int)edgeIndices.size() * sizeof(int);
|
||||
bufferDesc.Usage = D3D11_USAGE_DEFAULT;
|
||||
bufferDesc.BindFlags = D3D11_BIND_INDEX_BUFFER;
|
||||
bufferDesc.CPUAccessFlags = 0;
|
||||
bufferDesc.MiscFlags = 0;
|
||||
bufferDesc.StructureByteStride = sizeof(int);
|
||||
|
||||
D3D11_SUBRESOURCE_DATA subData;
|
||||
ZeroMemory(&subData, sizeof(subData));
|
||||
subData.pSysMem = &edgeIndices[0];
|
||||
subData.SysMemPitch = 0;
|
||||
subData.SysMemSlicePitch = 0;
|
||||
|
||||
HRESULT hr = device->CreateBuffer(&bufferDesc, &subData, &_edgeIndices);
|
||||
assert(_edgeIndices);
|
||||
|
||||
// edge sharpness
|
||||
SAFE_RELEASE(_edgeSharpness);
|
||||
SAFE_RELEASE(_edgeSharpnessSRV);
|
||||
ZeroMemory(&bufferDesc, sizeof(bufferDesc));
|
||||
bufferDesc.ByteWidth = (int)edgeSharpnesses.size() * sizeof(float);
|
||||
bufferDesc.Usage = D3D11_USAGE_DEFAULT;
|
||||
bufferDesc.BindFlags = D3D11_BIND_SHADER_RESOURCE;
|
||||
bufferDesc.CPUAccessFlags = 0;
|
||||
bufferDesc.MiscFlags = 0;
|
||||
bufferDesc.StructureByteStride = sizeof(float);
|
||||
|
||||
ZeroMemory(&subData, sizeof(subData));
|
||||
subData.pSysMem = &edgeSharpnesses[0];
|
||||
subData.SysMemPitch = 0;
|
||||
subData.SysMemSlicePitch = 0;
|
||||
|
||||
hr = device->CreateBuffer(&bufferDesc, &subData, &_edgeSharpness);
|
||||
assert(_edgeSharpness);
|
||||
|
||||
D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
|
||||
ZeroMemory(&srvDesc, sizeof(srvDesc));
|
||||
srvDesc.Format = DXGI_FORMAT_R32_FLOAT;
|
||||
srvDesc.ViewDimension = D3D11_SRV_DIMENSION_BUFFER;
|
||||
srvDesc.Buffer.NumElements = _numEdges;
|
||||
hr = device->CreateShaderResourceView(_edgeSharpness, &srvDesc, &_edgeSharpnessSRV);
|
||||
assert(_edgeSharpnessSRV);
|
||||
}
|
||||
|
65
examples/common/d3d11ControlMeshDisplay.h
Normal file
65
examples/common/d3d11ControlMeshDisplay.h
Normal file
@ -0,0 +1,65 @@
|
||||
//
|
||||
// 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_CONTROL_MESH_DISPLAY_H
|
||||
#define OPENSUBDIV_EXAMPLES_D3D11_CONTROL_MESH_DISPLAY_H
|
||||
|
||||
#include <d3d11.h>
|
||||
#include <far/topologyLevel.h>
|
||||
|
||||
class D3D11ControlMeshDisplay {
|
||||
public:
|
||||
D3D11ControlMeshDisplay(ID3D11DeviceContext *deviceContext);
|
||||
~D3D11ControlMeshDisplay();
|
||||
|
||||
void Draw(ID3D11Buffer *buffer, int stride,
|
||||
const float *modelViewProjectionMatrix);
|
||||
|
||||
void SetTopology(OpenSubdiv::Far::TopologyLevel const &level);
|
||||
|
||||
bool GetEdgesDisplay() const { return _displayEdges; }
|
||||
void SetEdgesDisplay(bool display) { _displayEdges = display; }
|
||||
bool GetVerticesDisplay() const { return _displayVertices; }
|
||||
void SetVerticesDisplay(bool display) { _displayVertices = display; }
|
||||
|
||||
private:
|
||||
bool createProgram();
|
||||
|
||||
bool _displayEdges;
|
||||
bool _displayVertices;
|
||||
|
||||
ID3D11DeviceContext *_deviceContext;
|
||||
ID3D11InputLayout *_inputLayout;
|
||||
ID3D11VertexShader *_vertexShader;
|
||||
ID3D11PixelShader *_pixelShader;
|
||||
ID3D11RasterizerState *_rasterizerState;
|
||||
ID3D11Buffer *_constantBuffer;
|
||||
ID3D11ShaderResourceView *_edgeSharpnessSRV;
|
||||
ID3D11Buffer *_edgeSharpness;
|
||||
ID3D11Buffer *_edgeIndices;
|
||||
|
||||
int _numEdges, _numPoints;
|
||||
};
|
||||
|
||||
#endif // OPENSUBDIV_EXAMPLES_D3D11_CONTROL_MESH_DISPLAY_H
|
224
examples/common/glControlMeshDisplay.cpp
Normal file
224
examples/common/glControlMeshDisplay.cpp
Normal file
@ -0,0 +1,224 @@
|
||||
//
|
||||
// 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 "glControlMeshDisplay.h"
|
||||
#include "../common/glUtils.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
GLControlMeshDisplay::GLControlMeshDisplay() :
|
||||
_displayEdges(true), _displayVertices(false),
|
||||
_program(0), _vao(0),
|
||||
_vertSharpness(0), _edgeSharpnessTexture(0), _edgeIndices(0),
|
||||
_numEdges(0), _numPoints(0) {
|
||||
}
|
||||
|
||||
GLControlMeshDisplay::~GLControlMeshDisplay() {
|
||||
if (_program) glDeleteProgram(_program);
|
||||
if (_vertSharpness) glDeleteBuffers(1, &_vertSharpness);
|
||||
if (_edgeSharpnessTexture) glDeleteTextures(1, &_edgeSharpnessTexture);
|
||||
if (_edgeIndices) glDeleteBuffers(1, &_edgeIndices);
|
||||
if (_vao) glDeleteVertexArrays(1, &_vao);
|
||||
}
|
||||
|
||||
bool
|
||||
GLControlMeshDisplay::createProgram() {
|
||||
if (_program != 0) glDeleteProgram(_program);
|
||||
|
||||
const std::string glsl_version = GLUtils::GetShaderVersionInclude();
|
||||
|
||||
static const std::string vsSrc =
|
||||
glsl_version +
|
||||
"in vec3 position; \n"
|
||||
"in float vertSharpness; \n"
|
||||
"out float sharpness; \n"
|
||||
"uniform mat4 mvpMatrix; \n"
|
||||
"void main() { \n"
|
||||
" sharpness = vertSharpness; \n"
|
||||
" gl_Position = mvpMatrix * vec4(position, 1); \n"
|
||||
"} \n";
|
||||
|
||||
static const std::string fsSrc =
|
||||
glsl_version +
|
||||
"in float sharpness; \n"
|
||||
"out vec4 color; \n"
|
||||
"uniform int drawMode = 0; \n"
|
||||
"uniform samplerBuffer edgeSharpness; \n"
|
||||
"vec4 sharpnessToColor(float s) { \n"
|
||||
" // 0.0 2.0 4.0 \n"
|
||||
" // green --- yellow --- red \n"
|
||||
" return vec4(min(1, s * 0.5), \n"
|
||||
" min(1, 2 - s * 0.5), \n"
|
||||
" 0, 1); \n"
|
||||
"} \n"
|
||||
"void main() { \n"
|
||||
" float sharp = sharpness; \n"
|
||||
" if (drawMode == 1) { \n"
|
||||
" sharp = texelFetch(edgeSharpness, gl_PrimitiveID).x; \n"
|
||||
" } \n"
|
||||
" color = sharpnessToColor(sharp); \n"
|
||||
"} \n";
|
||||
|
||||
GLuint vertexShader =
|
||||
GLUtils::CompileShader(GL_VERTEX_SHADER, vsSrc.c_str());
|
||||
GLuint fragmentShader =
|
||||
GLUtils::CompileShader(GL_FRAGMENT_SHADER, fsSrc.c_str());
|
||||
|
||||
_program = glCreateProgram();
|
||||
glAttachShader(_program, vertexShader);
|
||||
glAttachShader(_program, fragmentShader);
|
||||
glLinkProgram(_program);
|
||||
|
||||
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);
|
||||
printf("%s\n", infoLog);
|
||||
delete[] infoLog;
|
||||
exit(1);
|
||||
return false;
|
||||
}
|
||||
|
||||
_uniformMvpMatrix =
|
||||
glGetUniformLocation(_program, "mvpMatrix");
|
||||
_uniformDrawMode =
|
||||
glGetUniformLocation(_program, "drawMode");
|
||||
_uniformEdgeSharpness =
|
||||
glGetUniformLocation(_program, "edgeSharpness");
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
GLControlMeshDisplay::Draw(GLuint vbo, GLint stride,
|
||||
const float *modelViewProjectionMatrix) {
|
||||
if (_program == 0) {
|
||||
createProgram();
|
||||
if (_program == 0) return;
|
||||
}
|
||||
|
||||
if (_vao == 0) {
|
||||
glGenVertexArrays(1, &_vao);
|
||||
}
|
||||
glBindVertexArray(_vao);
|
||||
|
||||
glUseProgram(_program);
|
||||
|
||||
glUniformMatrix4fv(_uniformMvpMatrix,
|
||||
1, GL_FALSE, modelViewProjectionMatrix);
|
||||
glUniform1i(_uniformEdgeSharpness, 0);
|
||||
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
glBindTexture(GL_TEXTURE_BUFFER, _edgeSharpnessTexture);
|
||||
|
||||
// bind vbo to points
|
||||
glEnableVertexAttribArray(0);
|
||||
glEnableVertexAttribArray(1);
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, vbo);
|
||||
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, stride, 0);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, _vertSharpness);
|
||||
glVertexAttribPointer(1, 1, GL_FLOAT, GL_FALSE, 0, 0);
|
||||
|
||||
glPointSize(10.0);
|
||||
|
||||
// draw edges
|
||||
if (_displayEdges) {
|
||||
glUniform1i(_uniformDrawMode, 1);
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _edgeIndices);
|
||||
glDrawElements(GL_LINES, _numEdges*2, GL_UNSIGNED_INT, 0);
|
||||
}
|
||||
|
||||
// draw vertices
|
||||
if (_displayVertices) {
|
||||
glUniform1i(_uniformDrawMode, 0);
|
||||
glDrawArrays(GL_POINTS, 0, _numPoints);
|
||||
}
|
||||
|
||||
glPointSize(1.0f);
|
||||
|
||||
glDisableVertexAttribArray(0);
|
||||
glDisableVertexAttribArray(1);
|
||||
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
glBindVertexArray(0);
|
||||
|
||||
glUseProgram(0);
|
||||
}
|
||||
|
||||
void
|
||||
GLControlMeshDisplay::SetTopology(OpenSubdiv::Far::TopologyLevel const &level) {
|
||||
int nEdges = level.GetNumEdges();
|
||||
int nVerts = level.GetNumVertices();
|
||||
|
||||
std::vector<int> edgeIndices;
|
||||
std::vector<float> edgeSharpnesses;
|
||||
std::vector<float> vertSharpnesses;
|
||||
|
||||
edgeIndices.reserve(nEdges * 2);
|
||||
edgeSharpnesses.reserve(nEdges);
|
||||
vertSharpnesses.reserve(nVerts);
|
||||
|
||||
for (int i = 0; i < nEdges; ++i) {
|
||||
OpenSubdiv::Far::ConstIndexArray verts = level.GetEdgeVertices(i);
|
||||
edgeIndices.push_back(verts[0]);
|
||||
edgeIndices.push_back(verts[1]);
|
||||
edgeSharpnesses.push_back(level.GetEdgeSharpness(i));
|
||||
}
|
||||
|
||||
for (int i = 0; i < nVerts; ++i) {
|
||||
vertSharpnesses.push_back(level.GetVertexSharpness(i));
|
||||
}
|
||||
|
||||
if (_vertSharpness == 0) glGenBuffers(1, &_vertSharpness);
|
||||
if (_edgeIndices == 0) glGenBuffers(1, &_edgeIndices);
|
||||
if (_edgeSharpnessTexture == 0) glGenTextures(1, &_edgeSharpnessTexture);
|
||||
GLuint buffer = 0;
|
||||
glGenBuffers(1, &buffer);
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, _vertSharpness);
|
||||
glBufferData(GL_ARRAY_BUFFER, sizeof(float)*nVerts,
|
||||
&vertSharpnesses[0], GL_STATIC_DRAW);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, _edgeIndices);
|
||||
glBufferData(GL_ARRAY_BUFFER, sizeof(int)*nEdges*2,
|
||||
&edgeIndices[0], GL_STATIC_DRAW);
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, buffer);
|
||||
glBufferData(GL_ARRAY_BUFFER, sizeof(float)*nEdges,
|
||||
&edgeSharpnesses[0], GL_STATIC_DRAW);
|
||||
|
||||
glBindTexture(GL_TEXTURE_BUFFER, _edgeSharpnessTexture);
|
||||
glTexBuffer(GL_TEXTURE_BUFFER, GL_R32F, buffer);
|
||||
glBindTexture(GL_TEXTURE_BUFFER, 0);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
|
||||
glDeleteBuffers(1, &buffer);
|
||||
|
||||
_numEdges = nEdges;
|
||||
_numPoints = nVerts;
|
||||
}
|
||||
|
65
examples/common/glControlMeshDisplay.h
Normal file
65
examples/common/glControlMeshDisplay.h
Normal file
@ -0,0 +1,65 @@
|
||||
//
|
||||
// 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_CONTROL_MESH_DISPLAY_H
|
||||
#define OPENSUBDIV_EXAMPLES_GL_CONTROL_MESH_DISPLAY_H
|
||||
|
||||
#include <osd/opengl.h>
|
||||
#include <far/topologyLevel.h>
|
||||
|
||||
class GLControlMeshDisplay {
|
||||
public:
|
||||
GLControlMeshDisplay();
|
||||
~GLControlMeshDisplay();
|
||||
|
||||
void Draw(GLuint pointsVBO, GLint stride,
|
||||
const float *modelViewProjectionMatrix);
|
||||
|
||||
void SetTopology(OpenSubdiv::Far::TopologyLevel const &level);
|
||||
|
||||
bool GetEdgesDisplay() const { return _displayEdges; }
|
||||
void SetEdgesDisplay(bool display) { _displayEdges = display; }
|
||||
bool GetVerticesDisplay() const { return _displayVertices; }
|
||||
void SetVerticesDisplay(bool display) { _displayVertices = display; }
|
||||
|
||||
private:
|
||||
bool createProgram();
|
||||
|
||||
bool _displayEdges;
|
||||
bool _displayVertices;
|
||||
|
||||
GLuint _program;
|
||||
GLuint _uniformMvpMatrix;
|
||||
GLuint _uniformDrawMode;
|
||||
GLuint _uniformEdgeSharpness;
|
||||
|
||||
GLuint _vao;
|
||||
GLuint _vertSharpness;
|
||||
GLuint _edgeSharpnessTexture;
|
||||
GLuint _edgeIndices;
|
||||
|
||||
int _numEdges, _numPoints;
|
||||
};
|
||||
|
||||
#endif // OPENSUBDIV_EXAMPLES_GL_CONTROL_MESH_DISPLAY_H
|
@ -63,6 +63,7 @@ OpenSubdiv::Osd::D3D11LegacyGregoryPatchTable *g_legacyGregoryPatchTable = NULL;
|
||||
#include "../../regression/common/far_utils.h"
|
||||
#include "../common/stopwatch.h"
|
||||
#include "../common/simple_math.h"
|
||||
#include "../common/d3d11ControlMeshDisplay.h"
|
||||
#include "../common/d3d11Hud.h"
|
||||
#include "../common/d3d11Utils.h"
|
||||
#include "../common/d3d11ShaderCache.h"
|
||||
@ -100,8 +101,8 @@ enum EndCap { kEndCapNone = 0,
|
||||
kEndCapGregoryBasis,
|
||||
kEndCapLegacyGregory };
|
||||
|
||||
enum HudCheckBox { kHUD_CB_DISPLAY_CAGE_EDGES,
|
||||
kHUD_CB_DISPLAY_CAGE_VERTS,
|
||||
enum HudCheckBox { kHUD_CB_DISPLAY_CONTROL_MESH_EDGES,
|
||||
kHUD_CB_DISPLAY_CONTROL_MESH_VERTS,
|
||||
kHUD_CB_ANIMATE_VERTICES,
|
||||
kHUD_CB_DISPLAY_PATCH_COLOR,
|
||||
kHUD_CB_DISPLAY_PATCH_CVs,
|
||||
@ -122,8 +123,6 @@ int g_freeze = 0,
|
||||
g_adaptive = 1,
|
||||
g_endCap = kEndCapBSplineBasis,
|
||||
g_singleCreasePatch = 1,
|
||||
g_drawCageEdges = 1,
|
||||
g_drawCageVertices = 0,
|
||||
g_drawPatchCVs = 0,
|
||||
g_drawNormals = 0,
|
||||
g_mbutton[3] = {0, 0, 0};
|
||||
@ -146,6 +145,8 @@ int g_width = 1024,
|
||||
g_height = 1024;
|
||||
|
||||
D3D11hud *g_hud = NULL;
|
||||
D3D11ControlMeshDisplay *g_controlMeshDisplay = NULL;
|
||||
float g_modelViewProjectionMatrix[16];
|
||||
|
||||
// performance
|
||||
float g_cpuTime = 0;
|
||||
@ -164,10 +165,6 @@ int g_tessLevelMin = 1;
|
||||
int g_kernel = kCPU;
|
||||
float g_moveScale = 0.0f;
|
||||
|
||||
std::vector<int> g_coarseEdges;
|
||||
std::vector<float> g_coarseEdgeSharpness;
|
||||
std::vector<float> g_coarseVertexSharpness;
|
||||
|
||||
ID3D11Device * g_pd3dDevice = NULL;
|
||||
ID3D11DeviceContext * g_pd3dDeviceContext = NULL;
|
||||
IDXGISwapChain * g_pSwapChain = NULL;
|
||||
@ -278,24 +275,9 @@ createOsdMesh(ShapeDesc const & shapeDesc, int level, int kernel, Scheme scheme=
|
||||
|
||||
// save coarse topology (used for coarse mesh drawing)
|
||||
Far::TopologyLevel const & refBaseLevel = refiner->GetLevel(0);
|
||||
g_controlMeshDisplay->SetTopology(refBaseLevel);
|
||||
|
||||
int nedges = refBaseLevel.GetNumEdges(),
|
||||
nverts = refBaseLevel.GetNumVertices();
|
||||
|
||||
g_coarseEdges.resize(nedges*2);
|
||||
g_coarseEdgeSharpness.resize(nedges);
|
||||
g_coarseVertexSharpness.resize(nverts);
|
||||
|
||||
for(int i=0; i<nedges; ++i) {
|
||||
IndexArray verts = refBaseLevel.GetEdgeVertices(i);
|
||||
g_coarseEdges[i*2 ]=verts[0];
|
||||
g_coarseEdges[i*2+1]=verts[1];
|
||||
g_coarseEdgeSharpness[i]=refBaseLevel.GetEdgeSharpness(i);
|
||||
}
|
||||
|
||||
for(int i=0; i<nverts; ++i) {
|
||||
g_coarseVertexSharpness[i]=refBaseLevel.GetVertexSharpness(i);
|
||||
}
|
||||
int nverts = refBaseLevel.GetNumVertices();
|
||||
|
||||
g_orgPositions=shape->verts;
|
||||
|
||||
@ -689,6 +671,8 @@ bindProgram(Effect effect, OpenSubdiv::Osd::PatchArray const & patch) {
|
||||
perspective(pData->ProjectionMatrix, 45.0, aspect, 0.01f, 500.0);
|
||||
multMatrix(pData->ModelViewProjectionMatrix, pData->ModelViewMatrix, pData->ProjectionMatrix);
|
||||
|
||||
memcpy(g_modelViewProjectionMatrix, pData->ModelViewProjectionMatrix, sizeof(float) * 16);
|
||||
|
||||
g_pd3dDeviceContext->Unmap( g_pcbPerFrame, 0 );
|
||||
}
|
||||
|
||||
@ -884,6 +868,9 @@ display() {
|
||||
patch.GetIndexBase(), 0);
|
||||
}
|
||||
|
||||
// draw the control mesh
|
||||
g_controlMeshDisplay->Draw(buffer, 6, g_modelViewProjectionMatrix);
|
||||
|
||||
g_fpsTimer.Stop();
|
||||
float elapsed = (float)g_fpsTimer.GetElapsed();
|
||||
g_fpsTimer.Start();
|
||||
@ -970,6 +957,9 @@ quit() {
|
||||
if (g_hud)
|
||||
delete g_hud;
|
||||
|
||||
if (g_controlMeshDisplay)
|
||||
delete g_controlMeshDisplay;
|
||||
|
||||
SAFE_RELEASE(g_pRasterizerState);
|
||||
SAFE_RELEASE(g_pInputLayout);
|
||||
SAFE_RELEASE(g_pDepthStencilState);
|
||||
@ -1097,11 +1087,11 @@ callbackSingleCreasePatch(bool checked, int /* a */) {
|
||||
static void
|
||||
callbackCheckBox(bool checked, int button) {
|
||||
switch (button) {
|
||||
case kHUD_CB_DISPLAY_CAGE_EDGES:
|
||||
g_drawCageEdges = checked;
|
||||
case kHUD_CB_DISPLAY_CONTROL_MESH_EDGES:
|
||||
g_controlMeshDisplay->SetEdgesDisplay(checked);
|
||||
break;
|
||||
case kHUD_CB_DISPLAY_CAGE_VERTS:
|
||||
g_drawCageVertices = checked;
|
||||
case kHUD_CB_DISPLAY_CONTROL_MESH_VERTS:
|
||||
g_controlMeshDisplay->SetVerticesDisplay(checked);
|
||||
break;
|
||||
case kHUD_CB_ANIMATE_VERTICES:
|
||||
g_moveScale = checked;
|
||||
@ -1161,23 +1151,28 @@ initHUD() {
|
||||
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');
|
||||
// g_hud->AddCheckBox("Show normal vector (E)", false, 10, 10, callbackDisplayNormal, 0, 'E');
|
||||
g_hud->AddCheckBox("Control edges (H)",
|
||||
g_controlMeshDisplay->GetEdgesDisplay(),
|
||||
10, 10, callbackCheckBox,
|
||||
kHUD_CB_DISPLAY_CONTROL_MESH_EDGES, 'H');
|
||||
g_hud->AddCheckBox("Control vertices (J)",
|
||||
g_controlMeshDisplay->GetVerticesDisplay(),
|
||||
10, 30, callbackCheckBox,
|
||||
kHUD_CB_DISPLAY_CONTROL_MESH_VERTS, 'J');
|
||||
|
||||
g_hud->AddCheckBox("Patch CVs (L)", false, 10, 10, callbackCheckBox, kHUD_CB_DISPLAY_PATCH_CVs, 'L');
|
||||
g_hud->AddCheckBox("Patch Color (P)", true, 10, 30, callbackCheckBox, kHUD_CB_DISPLAY_PATCH_COLOR, 'P');
|
||||
g_hud->AddCheckBox("Animate vertices (M)", g_moveScale != 0, 10, 50, callbackCheckBox, kHUD_CB_ANIMATE_VERTICES, 'M');
|
||||
g_hud->AddCheckBox("Freeze (spc)", false, 10, 70, callbackCheckBox, kHUD_CB_FREEZE, ' ');
|
||||
g_hud->AddCheckBox("Screen space LOD (V)", g_screenSpaceTess != 0, 10, 110, callbackCheckBox, kHUD_CB_VIEW_LOD, 'V');
|
||||
g_hud->AddCheckBox("Fractional spacing (T)", g_fractionalSpacing != 0, 10, 130, callbackCheckBox, kHUD_CB_FRACTIONAL_SPACING, 'T');
|
||||
g_hud->AddCheckBox("Frustum Patch Culling (B)", g_patchCull != 0, 10, 150, callbackCheckBox, kHUD_CB_PATCH_CULL, 'B');
|
||||
g_hud->AddCheckBox("Patch CVs (L)", false, 10, 50, callbackCheckBox, kHUD_CB_DISPLAY_PATCH_CVs, 'L');
|
||||
g_hud->AddCheckBox("Patch Color (P)", true, 10, 70, callbackCheckBox, kHUD_CB_DISPLAY_PATCH_COLOR, 'P');
|
||||
g_hud->AddCheckBox("Animate vertices (M)", g_moveScale != 0, 10, 110, callbackCheckBox, kHUD_CB_ANIMATE_VERTICES, 'M');
|
||||
g_hud->AddCheckBox("Freeze (spc)", false, 10, 130, callbackCheckBox, kHUD_CB_FREEZE, ' ');
|
||||
g_hud->AddCheckBox("Screen space LOD (V)", g_screenSpaceTess != 0, 10, 150, callbackCheckBox, kHUD_CB_VIEW_LOD, 'V');
|
||||
g_hud->AddCheckBox("Fractional spacing (T)", g_fractionalSpacing != 0, 10, 170, callbackCheckBox, kHUD_CB_FRACTIONAL_SPACING, 'T');
|
||||
g_hud->AddCheckBox("Frustum Patch Culling (B)", g_patchCull != 0, 10, 190, callbackCheckBox, kHUD_CB_PATCH_CULL, 'B');
|
||||
|
||||
g_hud->AddCheckBox("Adaptive (`)", true, 10, 190, callbackAdaptive, 0, '`');
|
||||
g_hud->AddCheckBox("Single Crease Patch (S)", g_singleCreasePatch!=0, 10, 210, callbackSingleCreasePatch, 0, 'S');
|
||||
g_hud->AddCheckBox("Adaptive (`)", true, 10, 230, callbackAdaptive, 0, '`');
|
||||
g_hud->AddCheckBox("Single Crease Patch (S)", g_singleCreasePatch!=0, 10, 250, callbackSingleCreasePatch, 0, 'S');
|
||||
|
||||
int endcap_pulldown = g_hud->AddPullDown(
|
||||
"End cap (E)", 10, 230, 200, callbackEndCap, 'E');
|
||||
"End cap (E)", 10, 270, 200, callbackEndCap, 'E');
|
||||
g_hud->AddPullDownButton(endcap_pulldown,"None",
|
||||
kEndCapNone,
|
||||
g_endCap == kEndCapNone);
|
||||
@ -1194,7 +1189,7 @@ initHUD() {
|
||||
for (int i = 1; i < 11; ++i) {
|
||||
char level[16];
|
||||
sprintf(level, "Lv. %d", i);
|
||||
g_hud->AddRadioButton(3, level, i==2, 10, 230+i*20, callbackLevel, i, '0'+(i%10));
|
||||
g_hud->AddRadioButton(3, level, i==2, 10, 290+i*20, callbackLevel, i, '0'+(i%10));
|
||||
}
|
||||
|
||||
int shapes_pulldown = g_hud->AddPullDown("Shape (N)", -300, 10, 300, callbackModel, 'n');
|
||||
@ -1318,6 +1313,9 @@ initD3D11(HWND hWnd) {
|
||||
g_pd3dDevice->CreateDepthStencilState(&depthStencilDesc, &g_pDepthStencilState);
|
||||
assert(g_pDepthStencilState);
|
||||
|
||||
// initialize control mesh display
|
||||
g_controlMeshDisplay = new D3D11ControlMeshDisplay(g_pd3dDeviceContext);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -27,76 +27,97 @@
|
||||
|
||||
struct ShapeDesc {
|
||||
|
||||
ShapeDesc(char const * iname, std::string const & idata, Scheme ischeme) :
|
||||
name(iname), data(idata), scheme(ischeme) { }
|
||||
ShapeDesc(char const * iname, std::string const & idata, Scheme ischeme,
|
||||
bool iIsLeftHanded = false) :
|
||||
name(iname), data(idata), scheme(ischeme), isLeftHanded(iIsLeftHanded) { }
|
||||
|
||||
std::string name,
|
||||
data;
|
||||
data;
|
||||
Scheme scheme;
|
||||
bool isLeftHanded;
|
||||
};
|
||||
|
||||
static std::vector<ShapeDesc> g_defaultShapes;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
static void initShapes() {
|
||||
// g_defaultShapes.push_back( ShapeDesc("bilinear_cube", bilinear_cube, kBilinear) );
|
||||
g_defaultShapes.push_back(ShapeDesc("catmark_cube_corner0", catmark_cube_corner0, kCatmark));
|
||||
g_defaultShapes.push_back(ShapeDesc("catmark_cube_corner1", catmark_cube_corner1, kCatmark));
|
||||
g_defaultShapes.push_back(ShapeDesc("catmark_cube_corner2", catmark_cube_corner2, kCatmark));
|
||||
g_defaultShapes.push_back(ShapeDesc("catmark_cube_corner3", catmark_cube_corner3, kCatmark));
|
||||
g_defaultShapes.push_back(ShapeDesc("catmark_cube_corner4", catmark_cube_corner4, kCatmark));
|
||||
g_defaultShapes.push_back(ShapeDesc("catmark_cube_creases0", catmark_cube_creases0, kCatmark));
|
||||
g_defaultShapes.push_back(ShapeDesc("catmark_cube_creases1", catmark_cube_creases1, kCatmark));
|
||||
g_defaultShapes.push_back(ShapeDesc("catmark_cube_creases2", catmark_cube_creases2, kCatmark));
|
||||
g_defaultShapes.push_back(ShapeDesc("catmark_cube", catmark_cube, kCatmark));
|
||||
g_defaultShapes.push_back(ShapeDesc("catmark_dart_edgecorner", catmark_dart_edgecorner, kCatmark));
|
||||
g_defaultShapes.push_back(ShapeDesc("catmark_dart_edgeonly", catmark_dart_edgeonly, kCatmark));
|
||||
g_defaultShapes.push_back(ShapeDesc("catmark_edgecorner", catmark_edgecorner, kCatmark));
|
||||
g_defaultShapes.push_back(ShapeDesc("catmark_edgeonly", catmark_edgeonly, kCatmark));
|
||||
g_defaultShapes.push_back(ShapeDesc("catmark_chaikin0", catmark_chaikin0, kCatmark));
|
||||
g_defaultShapes.push_back(ShapeDesc("catmark_chaikin1", catmark_chaikin1, kCatmark));
|
||||
g_defaultShapes.push_back(ShapeDesc("catmark_chaikin2", catmark_chaikin2, kCatmark));
|
||||
g_defaultShapes.push_back(ShapeDesc("catmark_fan", catmark_fan, kCatmark));
|
||||
g_defaultShapes.push_back(ShapeDesc("catmark_flap", catmark_flap, kCatmark));
|
||||
g_defaultShapes.push_back(ShapeDesc("catmark_flap2", catmark_flap2, kCatmark));
|
||||
g_defaultShapes.push_back(ShapeDesc("catmark_fvar_bound0", catmark_fvar_bound0, kCatmark));
|
||||
g_defaultShapes.push_back(ShapeDesc("catmark_fvar_bound1", catmark_fvar_bound1, kCatmark));
|
||||
g_defaultShapes.push_back(ShapeDesc("catmark_fvar_bound2", catmark_fvar_bound2, kCatmark));
|
||||
g_defaultShapes.push_back(ShapeDesc("catmark_gregory_test0", catmark_gregory_test0, kCatmark));
|
||||
g_defaultShapes.push_back(ShapeDesc("catmark_gregory_test1", catmark_gregory_test1, kCatmark));
|
||||
g_defaultShapes.push_back(ShapeDesc("catmark_gregory_test2", catmark_gregory_test2, kCatmark));
|
||||
g_defaultShapes.push_back(ShapeDesc("catmark_gregory_test3", catmark_gregory_test3, kCatmark));
|
||||
g_defaultShapes.push_back(ShapeDesc("catmark_gregory_test4", catmark_gregory_test4, kCatmark));
|
||||
g_defaultShapes.push_back(ShapeDesc("catmark_gregory_test5", catmark_gregory_test5, kCatmark));
|
||||
g_defaultShapes.push_back(ShapeDesc("catmark_gregory_test6", catmark_gregory_test6, kCatmark));
|
||||
g_defaultShapes.push_back(ShapeDesc("catmark_gregory_test7", catmark_gregory_test7, kCatmark));
|
||||
g_defaultShapes.push_back(ShapeDesc("catmark_hole_test1", catmark_hole_test1, kCatmark));
|
||||
g_defaultShapes.push_back(ShapeDesc("catmark_hole_test2", catmark_hole_test2, kCatmark));
|
||||
g_defaultShapes.push_back(ShapeDesc("catmark_hole_test3", catmark_hole_test3, kCatmark));
|
||||
g_defaultShapes.push_back(ShapeDesc("catmark_hole_test4", catmark_hole_test4, kCatmark));
|
||||
g_defaultShapes.push_back(ShapeDesc("catmark_lefthanded", catmark_lefthanded, kCatmark, true /*isLeftHanded*/));
|
||||
g_defaultShapes.push_back(ShapeDesc("catmark_righthanded", catmark_righthanded, kCatmark));
|
||||
g_defaultShapes.push_back(ShapeDesc("catmark_pole8", catmark_pole8, kCatmark));
|
||||
g_defaultShapes.push_back(ShapeDesc("catmark_pole64", catmark_pole64, kCatmark));
|
||||
g_defaultShapes.push_back(ShapeDesc("catmark_pole360", catmark_pole360, kCatmark));
|
||||
g_defaultShapes.push_back(ShapeDesc("catmark_nonman_quadpole8", catmark_nonman_quadpole8, kCatmark));
|
||||
g_defaultShapes.push_back(ShapeDesc("catmark_nonman_quadpole64", catmark_nonman_quadpole64, kCatmark));
|
||||
g_defaultShapes.push_back(ShapeDesc("catmark_nonman_quadpole360", catmark_nonman_quadpole360, kCatmark));
|
||||
g_defaultShapes.push_back(ShapeDesc("catmark_pyramid_creases0", catmark_pyramid_creases0, kCatmark));
|
||||
g_defaultShapes.push_back(ShapeDesc("catmark_pyramid_creases1", catmark_pyramid_creases1, kCatmark));
|
||||
g_defaultShapes.push_back(ShapeDesc("catmark_pyramid", catmark_pyramid, kCatmark));
|
||||
g_defaultShapes.push_back(ShapeDesc("catmark_tent_creases0", catmark_tent_creases0, kCatmark));
|
||||
g_defaultShapes.push_back(ShapeDesc("catmark_tent_creases1", catmark_tent_creases1, kCatmark));
|
||||
g_defaultShapes.push_back(ShapeDesc("catmark_tent", catmark_tent, kCatmark));
|
||||
g_defaultShapes.push_back(ShapeDesc("catmark_torus", catmark_torus, kCatmark));
|
||||
g_defaultShapes.push_back(ShapeDesc("catmark_torus_creases0", catmark_torus_creases0, kCatmark));
|
||||
g_defaultShapes.push_back(ShapeDesc("catmark_single_crease", catmark_single_crease, kCatmark));
|
||||
g_defaultShapes.push_back(ShapeDesc("catmark_smoothtris0", catmark_smoothtris0, kCatmark));
|
||||
g_defaultShapes.push_back(ShapeDesc("catmark_smoothtris1", catmark_smoothtris1, kCatmark));
|
||||
// g_defaultShapes.push_back( ShapeDesc("catmark_square_hedit0", catmark_square_hedit0, kCatmark ) );
|
||||
// g_defaultShapes.push_back( ShapeDesc("catmark_square_hedit1", catmark_square_hedit1, kCatmark ) );
|
||||
// g_defaultShapes.push_back( ShapeDesc("catmark_square_hedit2", catmark_square_hedit2, kCatmark ) );
|
||||
// g_defaultShapes.push_back( ShapeDesc("catmark_square_hedit3", catmark_square_hedit3, kCatmark ) );
|
||||
g_defaultShapes.push_back(ShapeDesc("catmark_bishop", catmark_bishop, kCatmark));
|
||||
g_defaultShapes.push_back(ShapeDesc("catmark_car", catmark_car, kCatmark));
|
||||
g_defaultShapes.push_back(ShapeDesc("catmark_helmet", catmark_helmet, kCatmark));
|
||||
g_defaultShapes.push_back(ShapeDesc("catmark_pawn", catmark_pawn, kCatmark));
|
||||
g_defaultShapes.push_back(ShapeDesc("catmark_rook", catmark_rook, kCatmark));
|
||||
|
||||
g_defaultShapes.push_back( ShapeDesc("catmark_cube_corner0", catmark_cube_corner0, kCatmark ) );
|
||||
g_defaultShapes.push_back( ShapeDesc("catmark_cube_corner1", catmark_cube_corner1, kCatmark ) );
|
||||
g_defaultShapes.push_back( ShapeDesc("catmark_cube_corner2", catmark_cube_corner2, kCatmark ) );
|
||||
g_defaultShapes.push_back( ShapeDesc("catmark_cube_corner3", catmark_cube_corner3, kCatmark ) );
|
||||
g_defaultShapes.push_back( ShapeDesc("catmark_cube_corner4", catmark_cube_corner4, kCatmark ) );
|
||||
g_defaultShapes.push_back( ShapeDesc("catmark_cube_creases0", catmark_cube_creases0, kCatmark ) );
|
||||
g_defaultShapes.push_back( ShapeDesc("catmark_cube_creases1", catmark_cube_creases1, kCatmark ) );
|
||||
g_defaultShapes.push_back( ShapeDesc("catmark_cube", catmark_cube, kCatmark ) );
|
||||
g_defaultShapes.push_back( ShapeDesc("catmark_dart_edgecorner", catmark_dart_edgecorner, kCatmark ) );
|
||||
g_defaultShapes.push_back( ShapeDesc("catmark_dart_edgeonly", catmark_dart_edgeonly, kCatmark ) );
|
||||
g_defaultShapes.push_back( ShapeDesc("catmark_edgecorner", catmark_edgecorner, kCatmark ) );
|
||||
g_defaultShapes.push_back( ShapeDesc("catmark_edgeonly", catmark_edgeonly, kCatmark ) );
|
||||
g_defaultShapes.push_back( ShapeDesc("catmark_chaikin0", catmark_chaikin0, kCatmark ) );
|
||||
g_defaultShapes.push_back( ShapeDesc("catmark_chaikin1", catmark_chaikin1, kCatmark ) );
|
||||
g_defaultShapes.push_back( ShapeDesc("catmark_chaikin2", catmark_chaikin2, kCatmark ) );
|
||||
g_defaultShapes.push_back( ShapeDesc("catmark_fan", catmark_fan, kCatmark ) );
|
||||
g_defaultShapes.push_back( ShapeDesc("catmark_flap", catmark_flap, kCatmark ) );
|
||||
g_defaultShapes.push_back( ShapeDesc("catmark_flap2", catmark_flap2, kCatmark ) );
|
||||
g_defaultShapes.push_back( ShapeDesc("catmark_gregory_test1", catmark_gregory_test1, kCatmark ) );
|
||||
g_defaultShapes.push_back( ShapeDesc("catmark_gregory_test2", catmark_gregory_test2, kCatmark ) );
|
||||
g_defaultShapes.push_back( ShapeDesc("catmark_gregory_test3", catmark_gregory_test3, kCatmark ) );
|
||||
g_defaultShapes.push_back( ShapeDesc("catmark_gregory_test4", catmark_gregory_test4, kCatmark ) );
|
||||
g_defaultShapes.push_back( ShapeDesc("catmark_gregory_test5", catmark_gregory_test5, kCatmark ) );
|
||||
g_defaultShapes.push_back( ShapeDesc("catmark_gregory_test6", catmark_gregory_test6, kCatmark ) );
|
||||
g_defaultShapes.push_back( ShapeDesc("catmark_gregory_test7", catmark_gregory_test7, kCatmark ) );
|
||||
g_defaultShapes.push_back( ShapeDesc("catmark_hole_test1", catmark_hole_test1, kCatmark ) );
|
||||
g_defaultShapes.push_back( ShapeDesc("catmark_hole_test2", catmark_hole_test2, kCatmark ) );
|
||||
g_defaultShapes.push_back( ShapeDesc("catmark_pyramid_creases0", catmark_pyramid_creases0, kCatmark ) );
|
||||
g_defaultShapes.push_back( ShapeDesc("catmark_pyramid_creases1", catmark_pyramid_creases1, kCatmark ) );
|
||||
g_defaultShapes.push_back( ShapeDesc("catmark_pyramid", catmark_pyramid, kCatmark ) );
|
||||
g_defaultShapes.push_back( ShapeDesc("catmark_tent_creases0", catmark_tent_creases0, kCatmark ) );
|
||||
g_defaultShapes.push_back( ShapeDesc("catmark_tent_creases1", catmark_tent_creases1 , kCatmark ) );
|
||||
g_defaultShapes.push_back( ShapeDesc("catmark_tent", catmark_tent, kCatmark ) );
|
||||
g_defaultShapes.push_back( ShapeDesc("catmark_torus", catmark_torus, kCatmark ) );
|
||||
g_defaultShapes.push_back( ShapeDesc("catmark_torus_creases0", catmark_torus_creases0, kCatmark ) );
|
||||
// g_defaultShapes.push_back( ShapeDesc("catmark_square_hedit0", catmark_square_hedit0, kCatmark ) );
|
||||
// g_defaultShapes.push_back( ShapeDesc("catmark_square_hedit1", catmark_square_hedit1, kCatmark ) );
|
||||
// g_defaultShapes.push_back( ShapeDesc("catmark_square_hedit2", catmark_square_hedit2, kCatmark ) );
|
||||
// g_defaultShapes.push_back( ShapeDesc("catmark_square_hedit3", catmark_square_hedit3, kCatmark ) );
|
||||
g_defaultShapes.push_back( ShapeDesc("catmark_bishop", catmark_bishop, kCatmark ) );
|
||||
g_defaultShapes.push_back( ShapeDesc("catmark_car", catmark_car, kCatmark ) );
|
||||
g_defaultShapes.push_back( ShapeDesc("catmark_helmet", catmark_helmet, kCatmark ) );
|
||||
g_defaultShapes.push_back( ShapeDesc("catmark_pawn", catmark_pawn, kCatmark ) );
|
||||
g_defaultShapes.push_back( ShapeDesc("catmark_rook", catmark_rook, kCatmark ) );
|
||||
g_defaultShapes.push_back(ShapeDesc("bilinear_cube", bilinear_cube, kBilinear));
|
||||
|
||||
// g_defaultShapes.push_back( ShapeDesc("bilinear_cube", bilinear_cube, kBilinear ) );
|
||||
|
||||
// g_defaultShapes.push_back( ShapeDesc("loop_cube_creases0", loop_cube_creases0, kLoop ) );
|
||||
// g_defaultShapes.push_back( ShapeDesc("loop_cube_creases1", loop_cube_creases1, kLoop ) );
|
||||
// g_defaultShapes.push_back( ShapeDesc("loop_cube", loop_cube, kLoop ) );
|
||||
// g_defaultShapes.push_back( ShapeDesc("loop_icosahedron", loop_icosahedron, kLoop ) );
|
||||
// g_defaultShapes.push_back( ShapeDesc("loop_saddle_edgecorner", loop_saddle_edgecorner, kLoop ) );
|
||||
// g_defaultShapes.push_back( ShapeDesc("loop_saddle_edgeonly", loop_saddle_edgeonly, kLoop ) );
|
||||
// g_defaultShapes.push_back( ShapeDesc("loop_triangle_edgecorner", loop_triangle_edgecorner, kLoop ) );
|
||||
// g_defaultShapes.push_back( ShapeDesc("loop_triangle_edgeonly", loop_triangle_edgeonly, kLoop ) );
|
||||
// g_defaultShapes.push_back( ShapeDesc("loop_chaikin0", loop_chaikin0, kLoop ) );
|
||||
// g_defaultShapes.push_back( ShapeDesc("loop_chaikin1", loop_chaikin1, kLoop ) );
|
||||
g_defaultShapes.push_back(ShapeDesc("loop_cube_creases0", loop_cube_creases0, kLoop));
|
||||
g_defaultShapes.push_back(ShapeDesc("loop_cube_creases1", loop_cube_creases1, kLoop));
|
||||
g_defaultShapes.push_back(ShapeDesc("loop_cube", loop_cube, kLoop));
|
||||
g_defaultShapes.push_back(ShapeDesc("loop_icosahedron", loop_icosahedron, kLoop));
|
||||
g_defaultShapes.push_back(ShapeDesc("loop_saddle_edgecorner", loop_saddle_edgecorner, kLoop));
|
||||
g_defaultShapes.push_back(ShapeDesc("loop_saddle_edgeonly", loop_saddle_edgeonly, kLoop));
|
||||
g_defaultShapes.push_back(ShapeDesc("loop_triangle_edgecorner", loop_triangle_edgecorner, kLoop));
|
||||
g_defaultShapes.push_back(ShapeDesc("loop_triangle_edgeonly", loop_triangle_edgeonly, kLoop));
|
||||
g_defaultShapes.push_back(ShapeDesc("loop_chaikin0", loop_chaikin0, kLoop));
|
||||
g_defaultShapes.push_back(ShapeDesc("loop_chaikin1", loop_chaikin1, kLoop));
|
||||
g_defaultShapes.push_back(ShapeDesc("loop_pole8", loop_pole8, kLoop));
|
||||
g_defaultShapes.push_back(ShapeDesc("loop_pole64", loop_pole64, kLoop));
|
||||
g_defaultShapes.push_back(ShapeDesc("loop_pole360", loop_pole360, kLoop));
|
||||
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
|
@ -82,6 +82,7 @@ GLFWmonitor* g_primary=0;
|
||||
#include "../../regression/common/far_utils.h"
|
||||
#include "../common/stopwatch.h"
|
||||
#include "../common/simple_math.h"
|
||||
#include "../common/glControlMeshDisplay.h"
|
||||
#include "../common/glHud.h"
|
||||
|
||||
#include "init_shapes.h"
|
||||
@ -108,6 +109,13 @@ enum KernelType { kCPU = 0,
|
||||
enum EndCap { kEndCapBSplineBasis,
|
||||
kEndCapGregoryBasis };
|
||||
|
||||
enum HudCheckBox { kHUD_CB_DISPLAY_CONTROL_MESH_EDGES,
|
||||
kHUD_CB_DISPLAY_CONTROL_MESH_VERTS,
|
||||
kHUD_CB_ANIMATE_VERTICES,
|
||||
kHUD_CB_ANIMATE_PARTICLES,
|
||||
kHUD_CB_RANDOM_START,
|
||||
kHUD_CB_FREEZE };
|
||||
|
||||
enum DrawMode { kUV,
|
||||
kVARYING,
|
||||
kNORMAL,
|
||||
@ -124,16 +132,10 @@ int g_currentShape = 0,
|
||||
g_endCap = kEndCapBSplineBasis,
|
||||
g_numElements = 3;
|
||||
|
||||
std::vector<int> g_coarseEdges;
|
||||
std::vector<float> g_coarseEdgeSharpness;
|
||||
std::vector<float> g_coarseVertexSharpness;
|
||||
|
||||
int g_running = 1,
|
||||
g_width = 1024,
|
||||
g_height = 1024,
|
||||
g_fullscreen = 0,
|
||||
g_drawCageEdges = 1,
|
||||
g_drawCageVertices = 1,
|
||||
g_drawMode = kUV,
|
||||
g_prev_x = 0,
|
||||
g_prev_y = 0,
|
||||
@ -162,20 +164,20 @@ struct Transform {
|
||||
// performance
|
||||
float g_evalTime = 0;
|
||||
float g_computeTime = 0;
|
||||
float g_prevTime = 0;
|
||||
float g_currentTime = 0;
|
||||
Stopwatch g_fpsTimer;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
int g_nParticles = 65536;
|
||||
|
||||
bool g_randomStart = true;//false;
|
||||
bool g_animParticles = true;
|
||||
|
||||
GLuint g_cageEdgeVAO = 0,
|
||||
g_cageEdgeVBO = 0,
|
||||
g_cageVertexVAO = 0,
|
||||
g_cageVertexVBO = 0,
|
||||
g_samplesVAO=0;
|
||||
GLuint g_samplesVAO=0;
|
||||
|
||||
GLhud g_hud;
|
||||
GLControlMeshDisplay g_controlMeshDisplay;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
struct Program {
|
||||
@ -204,38 +206,6 @@ createRandomColors(int nverts, int stride, float * colors) {
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
static void
|
||||
createCoarseMesh(OpenSubdiv::Far::TopologyRefiner const & refiner) {
|
||||
|
||||
typedef OpenSubdiv::Far::ConstIndexArray IndexArray;
|
||||
|
||||
// save coarse topology (used for coarse mesh drawing)
|
||||
OpenSubdiv::Far::TopologyLevel const & refBaseLevel = refiner.GetLevel(0);
|
||||
|
||||
int nedges = refBaseLevel.GetNumEdges(),
|
||||
nverts = refBaseLevel.GetNumVertices();
|
||||
|
||||
g_coarseEdges.resize(nedges*2);
|
||||
g_coarseEdgeSharpness.resize(nedges);
|
||||
g_coarseVertexSharpness.resize(nverts);
|
||||
|
||||
for(int i=0; i<nedges; ++i) {
|
||||
IndexArray verts = refBaseLevel.GetEdgeVertices(i);
|
||||
g_coarseEdges[i*2 ]=verts[0];
|
||||
g_coarseEdges[i*2+1]=verts[1];
|
||||
g_coarseEdgeSharpness[i]=refBaseLevel.GetEdgeSharpness(i);
|
||||
}
|
||||
|
||||
for(int i=0; i<nverts; ++i) {
|
||||
g_coarseVertexSharpness[i]=refBaseLevel.GetVertexSharpness(i);
|
||||
}
|
||||
|
||||
// assign a randomly generated color for each vertex ofthe mesh
|
||||
g_varyingColors.resize(nverts*3);
|
||||
createRandomColors(nverts, 3, &g_varyingColors[0]);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
Far::PatchTable const * g_patchTable = NULL;
|
||||
|
||||
@ -243,6 +213,7 @@ Far::PatchTable const * g_patchTable = NULL;
|
||||
class EvalOutputBase {
|
||||
public:
|
||||
virtual ~EvalOutputBase() {}
|
||||
virtual GLuint BindSourceData() const = 0;
|
||||
virtual GLuint BindVertexData() const = 0;
|
||||
virtual GLuint BindDerivatives() const = 0;
|
||||
virtual GLuint BindPatchCoords() const = 0;
|
||||
@ -304,6 +275,9 @@ public:
|
||||
delete _vertexStencils;
|
||||
delete _varyingStencils;
|
||||
}
|
||||
virtual GLuint BindSourceData() const {
|
||||
return _srcData->BindVBO();
|
||||
}
|
||||
virtual GLuint BindVertexData() const {
|
||||
return _vertexData->BindVBO();
|
||||
}
|
||||
@ -416,7 +390,6 @@ private:
|
||||
};
|
||||
|
||||
EvalOutputBase *g_evalOutput = NULL;
|
||||
|
||||
STParticles * g_particles=0;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
@ -426,7 +399,7 @@ updateGeom() {
|
||||
|
||||
const float *p = &g_orgPositions[0];
|
||||
|
||||
float r = sin(g_frame*0.001f) * g_moveScale;
|
||||
float r = sin(g_frame*0.1f) * g_moveScale;
|
||||
|
||||
for (int i = 0; i < nverts; ++i) {
|
||||
//float move = 0.05f*cosf(p[0]*20+g_frame*0.01f);
|
||||
@ -465,7 +438,9 @@ updateGeom() {
|
||||
// Apply 'dynamics' update
|
||||
assert(g_particles);
|
||||
|
||||
g_particles->Update(g_evalTime); // XXXX g_evalTime is not really elapsed time...
|
||||
float elapsed = g_currentTime - g_prevTime;
|
||||
g_particles->Update(elapsed);
|
||||
g_prevTime = g_currentTime;
|
||||
|
||||
std::vector<OpenSubdiv::Osd::PatchCoord> const &patchCoords
|
||||
= g_particles->GetPatchCoords();
|
||||
@ -497,7 +472,6 @@ updateGeom() {
|
||||
static void
|
||||
createOsdMesh(ShapeDesc const & shapeDesc, int level) {
|
||||
|
||||
|
||||
Shape * shape = Shape::parseObj(shapeDesc.data.c_str(), shapeDesc.scheme);
|
||||
|
||||
// create Far mesh (topology)
|
||||
@ -515,7 +489,15 @@ createOsdMesh(ShapeDesc const & shapeDesc, int level) {
|
||||
|
||||
float speed = g_particles ? g_particles->GetSpeed() : 0.2f;
|
||||
|
||||
createCoarseMesh(*topologyRefiner);
|
||||
// save coarse topology (used for coarse mesh drawing)
|
||||
g_controlMeshDisplay.SetTopology(topologyRefiner->GetLevel(0));
|
||||
|
||||
// create random varying color
|
||||
{
|
||||
int numCoarseVerts = topologyRefiner->GetLevel(0).GetNumVertices();
|
||||
g_varyingColors.resize(numCoarseVerts*3);
|
||||
createRandomColors(numCoarseVerts, 3, &g_varyingColors[0]);
|
||||
}
|
||||
|
||||
Far::StencilTable const * vertexStencils = NULL;
|
||||
Far::StencilTable const * varyingStencils = NULL;
|
||||
@ -584,9 +566,16 @@ createOsdMesh(ShapeDesc const & shapeDesc, int level) {
|
||||
// note that for patch eval we need coarse+refined combined buffer.
|
||||
int nCoarseVertices = topologyRefiner->GetLevel(0).GetNumVertices();
|
||||
|
||||
// In following template instantiations, same type of vertex buffers are
|
||||
// used for both source and destination (first and second template
|
||||
// parameters), since we'd like to draw control mesh wireframe too in
|
||||
// this example viewer.
|
||||
// If we don't need to draw the coarse control mesh, the src buffer doesn't
|
||||
// have to be interoperable to GL (it can be CpuVertexBuffer etc).
|
||||
|
||||
delete g_evalOutput;
|
||||
if (g_kernel == kCPU) {
|
||||
g_evalOutput = new EvalOutput<Osd::CpuVertexBuffer,
|
||||
g_evalOutput = new EvalOutput<Osd::CpuGLVertexBuffer,
|
||||
Osd::CpuGLVertexBuffer,
|
||||
Far::StencilTable,
|
||||
Osd::CpuPatchTable,
|
||||
@ -595,7 +584,7 @@ createOsdMesh(ShapeDesc const & shapeDesc, int level) {
|
||||
nCoarseVertices, nverts, g_nParticles, g_patchTable);
|
||||
#ifdef OPENSUBDIV_HAS_OPENMP
|
||||
} else if (g_kernel == kOPENMP) {
|
||||
g_evalOutput = new EvalOutput<Osd::CpuVertexBuffer,
|
||||
g_evalOutput = new EvalOutput<Osd::CpuGLVertexBuffer,
|
||||
Osd::CpuGLVertexBuffer,
|
||||
Far::StencilTable,
|
||||
Osd::CpuPatchTable,
|
||||
@ -605,7 +594,7 @@ createOsdMesh(ShapeDesc const & shapeDesc, int level) {
|
||||
#endif
|
||||
#ifdef OPENSUBDIV_HAS_TBB
|
||||
} else if (g_kernel == kTBB) {
|
||||
g_evalOutput = new EvalOutput<Osd::CpuVertexBuffer,
|
||||
g_evalOutput = new EvalOutput<Osd::CpuGLVertexBuffer,
|
||||
Osd::CpuGLVertexBuffer,
|
||||
Far::StencilTable,
|
||||
Osd::CpuPatchTable,
|
||||
@ -615,7 +604,7 @@ createOsdMesh(ShapeDesc const & shapeDesc, int level) {
|
||||
#endif
|
||||
#ifdef OPENSUBDIV_HAS_CUDA
|
||||
} else if (g_kernel == kCUDA) {
|
||||
g_evalOutput = new EvalOutput<Osd::CudaVertexBuffer,
|
||||
g_evalOutput = new EvalOutput<Osd::CudaGLVertexBuffer,
|
||||
Osd::CudaGLVertexBuffer,
|
||||
Osd::CudaStencilTable,
|
||||
Osd::CudaPatchTable,
|
||||
@ -626,7 +615,7 @@ createOsdMesh(ShapeDesc const & shapeDesc, int level) {
|
||||
#ifdef OPENSUBDIV_HAS_OPENCL
|
||||
} else if (g_kernel == kCL) {
|
||||
static Osd::EvaluatorCacheT<Osd::CLEvaluator> clEvaluatorCache;
|
||||
g_evalOutput = new EvalOutput<Osd::CLVertexBuffer,
|
||||
g_evalOutput = new EvalOutput<Osd::CLGLVertexBuffer,
|
||||
Osd::CLGLVertexBuffer,
|
||||
Osd::CLStencilTable,
|
||||
Osd::CLPatchTable,
|
||||
@ -671,6 +660,9 @@ createOsdMesh(ShapeDesc const & shapeDesc, int level) {
|
||||
g_nParticles = g_particles->GetNumParticles();
|
||||
g_particles->SetSpeed(speed);
|
||||
|
||||
g_prevTime = -1;
|
||||
g_currentTime = 0;
|
||||
|
||||
updateGeom();
|
||||
|
||||
delete topologyRefiner;
|
||||
@ -767,126 +759,6 @@ linkDefaultProgram() {
|
||||
return true;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
static inline void
|
||||
setSharpnessColor(float s, float *r, float *g, float *b) {
|
||||
// 0.0 2.0 4.0
|
||||
// green --- yellow --- red
|
||||
*r = std::min(1.0f, s * 0.5f);
|
||||
*g = std::min(1.0f, 2.0f - s*0.5f);
|
||||
*b = 0;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
static void
|
||||
drawCageEdges() {
|
||||
|
||||
glUseProgram(g_defaultProgram.program);
|
||||
glUniformMatrix4fv(g_defaultProgram.uniformModelViewMatrix,
|
||||
1, GL_FALSE, g_transformData.ModelViewMatrix);
|
||||
glUniformMatrix4fv(g_defaultProgram.uniformProjectionMatrix,
|
||||
1, GL_FALSE, g_transformData.ProjectionMatrix);
|
||||
glUniform1i(g_defaultProgram.uniformDrawMode, 0);
|
||||
|
||||
std::vector<float> vbo;
|
||||
vbo.reserve(g_coarseEdges.size() * 6);
|
||||
float r, g, b;
|
||||
for (int i = 0; i < (int)g_coarseEdges.size(); i+=2) {
|
||||
setSharpnessColor(g_coarseEdgeSharpness[i/2], &r, &g, &b);
|
||||
for (int j = 0; j < 2; ++j) {
|
||||
vbo.push_back(g_positions[g_coarseEdges[i+j]*3]);
|
||||
vbo.push_back(g_positions[g_coarseEdges[i+j]*3+1]);
|
||||
vbo.push_back(g_positions[g_coarseEdges[i+j]*3+2]);
|
||||
vbo.push_back(r);
|
||||
vbo.push_back(g);
|
||||
vbo.push_back(b);
|
||||
}
|
||||
}
|
||||
|
||||
glBindVertexArray(g_cageEdgeVAO);
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, g_cageEdgeVBO);
|
||||
glBufferData(GL_ARRAY_BUFFER, (int)vbo.size() * sizeof(float), &vbo[0],
|
||||
GL_STATIC_DRAW);
|
||||
|
||||
glEnableVertexAttribArray(g_defaultProgram.attrPosition);
|
||||
glEnableVertexAttribArray(g_defaultProgram.attrColor);
|
||||
glDisableVertexAttribArray(g_defaultProgram.attrTangentU);
|
||||
glDisableVertexAttribArray(g_defaultProgram.attrTangentV);
|
||||
glDisableVertexAttribArray(g_defaultProgram.attrPatchCoord);
|
||||
glVertexAttribPointer(g_defaultProgram.attrPosition,
|
||||
3, GL_FLOAT, GL_FALSE, sizeof (GLfloat) * 6, 0);
|
||||
glVertexAttribPointer(g_defaultProgram.attrColor,
|
||||
3, GL_FLOAT, GL_FALSE, sizeof (GLfloat) * 6, (void*)12);
|
||||
|
||||
glDrawArrays(GL_LINES, 0, (int)g_coarseEdges.size());
|
||||
|
||||
glBindVertexArray(0);
|
||||
glUseProgram(0);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
static void
|
||||
drawCageVertices() {
|
||||
|
||||
glUseProgram(g_defaultProgram.program);
|
||||
glUniformMatrix4fv(g_defaultProgram.uniformModelViewMatrix,
|
||||
1, GL_FALSE, g_transformData.ModelViewMatrix);
|
||||
glUniformMatrix4fv(g_defaultProgram.uniformProjectionMatrix,
|
||||
1, GL_FALSE, g_transformData.ProjectionMatrix);
|
||||
glUniform1i(g_defaultProgram.uniformDrawMode, 0);
|
||||
|
||||
int numPoints = (int)g_positions.size()/3;
|
||||
std::vector<float> vbo;
|
||||
vbo.reserve(numPoints*6);
|
||||
float r, g, b;
|
||||
for (int i = 0; i < numPoints; ++i) {
|
||||
|
||||
switch (g_drawMode) {
|
||||
|
||||
case kVARYING : { r=g_varyingColors[i*3+0];
|
||||
g=g_varyingColors[i*3+1];
|
||||
b=g_varyingColors[i*3+2];
|
||||
} break;
|
||||
|
||||
case kUV : { setSharpnessColor(g_coarseVertexSharpness[i], &r, &g, &b);
|
||||
} break;
|
||||
|
||||
default : break;
|
||||
}
|
||||
|
||||
vbo.push_back(g_positions[i*3+0]);
|
||||
vbo.push_back(g_positions[i*3+1]);
|
||||
vbo.push_back(g_positions[i*3+2]);
|
||||
vbo.push_back(r);
|
||||
vbo.push_back(g);
|
||||
vbo.push_back(b);
|
||||
}
|
||||
|
||||
glBindVertexArray(g_cageVertexVAO);
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, g_cageVertexVBO);
|
||||
glBufferData(GL_ARRAY_BUFFER, (int)vbo.size() * sizeof(float), &vbo[0],
|
||||
GL_STATIC_DRAW);
|
||||
|
||||
glEnableVertexAttribArray(g_defaultProgram.attrPosition);
|
||||
glEnableVertexAttribArray(g_defaultProgram.attrColor);
|
||||
glDisableVertexAttribArray(g_defaultProgram.attrTangentU);
|
||||
glDisableVertexAttribArray(g_defaultProgram.attrTangentV);
|
||||
glDisableVertexAttribArray(g_defaultProgram.attrPatchCoord);
|
||||
glVertexAttribPointer(g_defaultProgram.attrPosition,
|
||||
3, GL_FLOAT, GL_FALSE, sizeof (GLfloat) * 6, 0);
|
||||
glVertexAttribPointer(g_defaultProgram.attrColor,
|
||||
3, GL_FLOAT, GL_FALSE, sizeof (GLfloat) * 6, (void*)12);
|
||||
|
||||
glPointSize(10.0f);
|
||||
glDrawArrays(GL_POINTS, 0, numPoints);
|
||||
glPointSize(1.0f);
|
||||
|
||||
glBindVertexArray(0);
|
||||
glUseProgram(0);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
static void
|
||||
drawSamples() {
|
||||
@ -976,18 +848,19 @@ display() {
|
||||
|
||||
drawSamples();
|
||||
|
||||
if (g_drawCageEdges)
|
||||
drawCageEdges();
|
||||
|
||||
if (g_drawCageVertices)
|
||||
drawCageVertices();
|
||||
// draw the control mesh
|
||||
g_controlMeshDisplay.Draw(
|
||||
g_evalOutput->BindSourceData(), 3*sizeof(float),
|
||||
g_transformData.ModelViewProjectionMatrix);
|
||||
|
||||
g_hud.GetFrameBuffer()->ApplyImageShader();
|
||||
|
||||
if (g_hud.IsVisible()) {
|
||||
g_fpsTimer.Stop();
|
||||
double fps = 1.0/g_fpsTimer.GetElapsed();
|
||||
double elapsed = g_fpsTimer.GetElapsed();
|
||||
g_fpsTimer.Start();
|
||||
double fps = 1.0/elapsed;
|
||||
if (g_animParticles) g_currentTime += (float)elapsed;
|
||||
|
||||
int nPatchCoords = (int)g_particles->GetPatchCoords().size();
|
||||
|
||||
@ -1180,44 +1053,37 @@ callbackLevel(int l) {
|
||||
createOsdMesh(g_defaultShapes[g_currentShape], g_level);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
static void
|
||||
callbackAnimate(bool checked, int /* m */) {
|
||||
g_moveScale = checked * 3.0f;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
static void
|
||||
callbackFreeze(bool checked, int /* f */) {
|
||||
g_freeze = checked;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
static void
|
||||
callbackCentered(bool checked, int /* f */) {
|
||||
g_randomStart = checked;
|
||||
createOsdMesh(g_defaultShapes[g_currentShape], g_level);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
static void
|
||||
callbackDisplayCageVertices(bool checked, int /* d */) {
|
||||
g_drawCageVertices = checked;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
static void
|
||||
callbackDisplayCageEdges(bool checked, int /* d */) {
|
||||
g_drawCageEdges = checked;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
static void
|
||||
callbackDisplayVaryingColors(int mode) {
|
||||
g_drawMode = mode;
|
||||
createOsdMesh(g_defaultShapes[g_currentShape], g_level);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
static void
|
||||
callbackCheckBox(bool checked, int button) {
|
||||
switch (button) {
|
||||
case kHUD_CB_DISPLAY_CONTROL_MESH_EDGES:
|
||||
g_controlMeshDisplay.SetEdgesDisplay(checked);
|
||||
break;
|
||||
case kHUD_CB_DISPLAY_CONTROL_MESH_VERTS:
|
||||
g_controlMeshDisplay.SetVerticesDisplay(checked);
|
||||
break;
|
||||
case kHUD_CB_ANIMATE_VERTICES:
|
||||
g_moveScale = checked;
|
||||
break;
|
||||
case kHUD_CB_ANIMATE_PARTICLES:
|
||||
g_animParticles = checked;
|
||||
break;
|
||||
case kHUD_CB_RANDOM_START:
|
||||
g_randomStart = checked;
|
||||
createOsdMesh(g_defaultShapes[g_currentShape], g_level);
|
||||
break;
|
||||
case kHUD_CB_FREEZE:
|
||||
g_freeze = checked;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
static void
|
||||
@ -1233,12 +1099,23 @@ initHUD() {
|
||||
|
||||
g_hud.SetFrameBuffer(new GLFrameBuffer);
|
||||
|
||||
g_hud.AddCheckBox("Cage Edges (H)", true, 10, 10, callbackDisplayCageEdges, 0, 'h');
|
||||
g_hud.AddCheckBox("Cage Verts (J)", true, 10, 30, callbackDisplayCageVertices, 0, 'j');
|
||||
g_hud.AddCheckBox("Animate vertices (M)", g_moveScale != 0, 10, 50, callbackAnimate, 0, 'm');
|
||||
g_hud.AddCheckBox("Freeze (spc)", false, 10, 70, callbackFreeze, 0, ' ');
|
||||
g_hud.AddCheckBox("Control edges (H)",
|
||||
g_controlMeshDisplay.GetEdgesDisplay(),
|
||||
10, 10, callbackCheckBox,
|
||||
kHUD_CB_DISPLAY_CONTROL_MESH_EDGES, 'h');
|
||||
g_hud.AddCheckBox("Control vertices (J)",
|
||||
g_controlMeshDisplay.GetVerticesDisplay(),
|
||||
10, 30, callbackCheckBox,
|
||||
kHUD_CB_DISPLAY_CONTROL_MESH_VERTS, 'j');
|
||||
g_hud.AddCheckBox("Animate vertices (M)", g_moveScale != 0,
|
||||
10, 50, callbackCheckBox, kHUD_CB_ANIMATE_VERTICES, 'm');
|
||||
g_hud.AddCheckBox("Animate particles (P)", g_animParticles != 0,
|
||||
10, 70, callbackCheckBox, kHUD_CB_ANIMATE_PARTICLES, 'p');
|
||||
g_hud.AddCheckBox("Freeze (spc)", g_freeze != 0,
|
||||
10, 90, callbackCheckBox, kHUD_CB_FREEZE, ' ');
|
||||
|
||||
g_hud.AddCheckBox("Random Start", g_randomStart, 10, 120, callbackCentered, 0);
|
||||
g_hud.AddCheckBox("Random Start", g_randomStart,
|
||||
10, 110, callbackCheckBox, kHUD_CB_RANDOM_START);
|
||||
|
||||
int compute_pulldown = g_hud.AddPullDown("Compute (K)", 475, 10, 300,
|
||||
callbackKernel, 'k');
|
||||
@ -1303,22 +1180,12 @@ initGL() {
|
||||
glDepthFunc(GL_LEQUAL);
|
||||
glCullFace(GL_BACK);
|
||||
glEnable(GL_CULL_FACE);
|
||||
|
||||
glGenVertexArrays(1, &g_cageVertexVAO);
|
||||
glGenVertexArrays(1, &g_cageEdgeVAO);
|
||||
glGenVertexArrays(1, &g_samplesVAO);
|
||||
glGenBuffers(1, &g_cageVertexVBO);
|
||||
glGenBuffers(1, &g_cageEdgeVBO);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
static void
|
||||
uninitGL() {
|
||||
|
||||
glDeleteBuffers(1, &g_cageVertexVBO);
|
||||
glDeleteBuffers(1, &g_cageEdgeVBO);
|
||||
glDeleteVertexArrays(1, &g_cageVertexVAO);
|
||||
glDeleteVertexArrays(1, &g_cageEdgeVAO);
|
||||
glDeleteVertexArrays(1, &g_samplesVAO);
|
||||
}
|
||||
|
||||
@ -1431,6 +1298,8 @@ int main(int argc, char **argv) {
|
||||
initHUD();
|
||||
callbackModel(g_currentShape);
|
||||
|
||||
g_fpsTimer.Start();
|
||||
|
||||
while (g_running) {
|
||||
idle();
|
||||
display();
|
||||
|
@ -271,7 +271,7 @@ STParticles::~STParticles() {
|
||||
void
|
||||
STParticles::Update(float deltaTime) {
|
||||
|
||||
if (fabs(GetSpeed()) < 0.001f) return;
|
||||
if (deltaTime == 0) return;
|
||||
float speed = GetSpeed() * std::max(0.001f, std::min(deltaTime, 0.5f));
|
||||
|
||||
_patchCoords.clear();
|
||||
|
@ -37,6 +37,7 @@ OpenSubdiv::Osd::GLMeshInterface *g_mesh = NULL;
|
||||
#include "../../regression/common/far_utils.h"
|
||||
#include "../common/stopwatch.h"
|
||||
#include "../common/simple_math.h"
|
||||
#include "../common/glControlMeshDisplay.h"
|
||||
#include "../common/glHud.h"
|
||||
#include "../common/glShaderCache.h"
|
||||
|
||||
@ -95,6 +96,7 @@ int g_width = 1600,
|
||||
g_height = 800;
|
||||
|
||||
GLhud g_hud;
|
||||
GLControlMeshDisplay g_controlMeshDisplay;
|
||||
|
||||
// geometry
|
||||
std::vector<float> g_orgPositions,
|
||||
@ -121,10 +123,6 @@ struct Transform {
|
||||
} g_transformData;
|
||||
|
||||
GLuint g_vao = 0;
|
||||
GLuint g_cageEdgeVAO = 0,
|
||||
g_cageEdgeVBO = 0,
|
||||
g_cageVertexVAO = 0,
|
||||
g_cageVertexVBO = 0;
|
||||
|
||||
std::vector<int> g_coarseEdges;
|
||||
std::vector<float> g_coarseEdgeSharpness;
|
||||
@ -335,9 +333,10 @@ updateGeom() {
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
static void
|
||||
createOsdMesh(ShapeDesc const & shapeDesc, int level, Scheme scheme = kCatmark) {
|
||||
|
||||
typedef OpenSubdiv::Far::ConstIndexArray IndexArray;
|
||||
rebuildMesh() {
|
||||
ShapeDesc const &shapeDesc = g_defaultShapes[g_currentShape];
|
||||
int level = g_level;
|
||||
Scheme scheme = g_defaultShapes[g_currentShape].scheme;
|
||||
|
||||
Shape * shape = Shape::parseObj(shapeDesc.data.c_str(), shapeDesc.scheme);
|
||||
|
||||
@ -352,24 +351,7 @@ createOsdMesh(ShapeDesc const & shapeDesc, int level, Scheme scheme = kCatmark)
|
||||
OpenSubdiv::Far::TopologyRefinerFactory<Shape>::Options(sdctype, sdcoptions));
|
||||
|
||||
// save coarse topology (used for coarse mesh drawing)
|
||||
OpenSubdiv::Far::TopologyLevel const & refBaseLevel = refiner->GetLevel(0);
|
||||
int nedges = refBaseLevel.GetNumEdges(),
|
||||
nverts = refBaseLevel.GetNumVertices();
|
||||
|
||||
g_coarseEdges.resize(nedges*2);
|
||||
g_coarseEdgeSharpness.resize(nedges);
|
||||
g_coarseVertexSharpness.resize(nverts);
|
||||
|
||||
for(int i=0; i<nedges; ++i) {
|
||||
IndexArray verts = refBaseLevel.GetEdgeVertices(i);
|
||||
g_coarseEdges[i*2 ]=verts[0];
|
||||
g_coarseEdges[i*2+1]=verts[1];
|
||||
g_coarseEdgeSharpness[i]=refBaseLevel.GetEdgeSharpness(i);
|
||||
}
|
||||
|
||||
for(int i=0; i<nverts; ++i) {
|
||||
g_coarseVertexSharpness[i]=refBaseLevel.GetVertexSharpness(i);
|
||||
}
|
||||
g_controlMeshDisplay.SetTopology(refiner->GetLevel(0));
|
||||
|
||||
g_orgPositions=shape->verts;
|
||||
g_normals.resize(g_orgPositions.size(), 0.0f);
|
||||
@ -450,100 +432,6 @@ fitFrame() {
|
||||
g_uvScale = 1.0;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
static inline void
|
||||
setSharpnessColor(float s, float *r, float *g, float *b) {
|
||||
|
||||
// 0.0 2.0 4.0
|
||||
// green --- yellow --- red
|
||||
*r = std::min(1.0f, s * 0.5f);
|
||||
*g = std::min(1.0f, 2.0f - s*0.5f);
|
||||
*b = 0;
|
||||
}
|
||||
|
||||
static void
|
||||
drawCageEdges() {
|
||||
|
||||
glUseProgram(g_defaultProgram.program);
|
||||
glUniformMatrix4fv(g_defaultProgram.uniformModelViewProjectionMatrix,
|
||||
1, GL_FALSE, g_transformData.ModelViewProjectionMatrix);
|
||||
|
||||
std::vector<float> vbo;
|
||||
vbo.reserve(g_coarseEdges.size() * 6);
|
||||
float r, g, b;
|
||||
for (int i = 0; i < (int)g_coarseEdges.size(); i+=2) {
|
||||
setSharpnessColor(g_coarseEdgeSharpness[i/2], &r, &g, &b);
|
||||
for (int j = 0; j < 2; ++j) {
|
||||
vbo.push_back(g_positions[g_coarseEdges[i+j]*3]);
|
||||
vbo.push_back(g_positions[g_coarseEdges[i+j]*3+1]);
|
||||
vbo.push_back(g_positions[g_coarseEdges[i+j]*3+2]);
|
||||
vbo.push_back(r);
|
||||
vbo.push_back(g);
|
||||
vbo.push_back(b);
|
||||
}
|
||||
}
|
||||
|
||||
glBindVertexArray(g_cageEdgeVAO);
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, g_cageEdgeVBO);
|
||||
glBufferData(GL_ARRAY_BUFFER, (int)vbo.size() * sizeof(float), &vbo[0],
|
||||
GL_STATIC_DRAW);
|
||||
|
||||
glEnableVertexAttribArray(g_defaultProgram.attrPosition);
|
||||
glEnableVertexAttribArray(g_defaultProgram.attrColor);
|
||||
glVertexAttribPointer(g_defaultProgram.attrPosition,
|
||||
3, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 6, 0);
|
||||
glVertexAttribPointer(g_defaultProgram.attrColor,
|
||||
3, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 6, (void*)12);
|
||||
|
||||
glDrawArrays(GL_LINES, 0, (int)g_coarseEdges.size());
|
||||
|
||||
glBindVertexArray(0);
|
||||
glUseProgram(0);
|
||||
}
|
||||
|
||||
static void
|
||||
drawCageVertices() {
|
||||
|
||||
glUseProgram(g_defaultProgram.program);
|
||||
glUniformMatrix4fv(g_defaultProgram.uniformModelViewProjectionMatrix,
|
||||
1, GL_FALSE, g_transformData.ModelViewProjectionMatrix);
|
||||
|
||||
int numPoints = (int)g_positions.size()/3;
|
||||
std::vector<float> vbo;
|
||||
vbo.reserve(numPoints*6);
|
||||
float r, g, b;
|
||||
for (int i = 0; i < numPoints; ++i) {
|
||||
setSharpnessColor(g_coarseVertexSharpness[i], &r, &g, &b);
|
||||
vbo.push_back(g_positions[i*3+0]);
|
||||
vbo.push_back(g_positions[i*3+1]);
|
||||
vbo.push_back(g_positions[i*3+2]);
|
||||
vbo.push_back(r);
|
||||
vbo.push_back(g);
|
||||
vbo.push_back(b);
|
||||
}
|
||||
|
||||
glBindVertexArray(g_cageVertexVAO);
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, g_cageVertexVBO);
|
||||
glBufferData(GL_ARRAY_BUFFER, (int)vbo.size() * sizeof(float), &vbo[0],
|
||||
GL_STATIC_DRAW);
|
||||
|
||||
glEnableVertexAttribArray(g_defaultProgram.attrPosition);
|
||||
glEnableVertexAttribArray(g_defaultProgram.attrColor);
|
||||
glVertexAttribPointer(g_defaultProgram.attrPosition,
|
||||
3, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 6, 0);
|
||||
glVertexAttribPointer(g_defaultProgram.attrColor,
|
||||
3, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 6, (void*)12);
|
||||
|
||||
glPointSize(10.0f);
|
||||
glDrawArrays(GL_POINTS, 0, numPoints);
|
||||
glPointSize(1.0f);
|
||||
|
||||
glBindVertexArray(0);
|
||||
glUseProgram(0);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
union Effect {
|
||||
@ -851,7 +739,7 @@ display() {
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
|
||||
// make sure that the vertex buffer is interoped back as a GL resources.
|
||||
g_mesh->BindVertexBuffer();
|
||||
GLuint vbo = g_mesh->BindVertexBuffer();
|
||||
|
||||
glBindVertexArray(g_vao);
|
||||
|
||||
@ -882,8 +770,9 @@ display() {
|
||||
glBindVertexArray(0);
|
||||
glUseProgram(0);
|
||||
|
||||
drawCageEdges();
|
||||
drawCageVertices();
|
||||
// draw the control mesh
|
||||
g_controlMeshDisplay.Draw(vbo, 3*sizeof(float),
|
||||
g_transformData.ModelViewProjectionMatrix);
|
||||
|
||||
// ---------------------------------------------
|
||||
// uv viewport
|
||||
@ -981,12 +870,7 @@ mouse(GLFWwindow *, int button, int state, int /* mods */) {
|
||||
static void
|
||||
uninitGL() {
|
||||
|
||||
glDeleteBuffers(1, &g_cageVertexVBO);
|
||||
glDeleteBuffers(1, &g_cageEdgeVBO);
|
||||
glDeleteVertexArrays(1, &g_vao);
|
||||
glDeleteVertexArrays(1, &g_cageVertexVAO);
|
||||
glDeleteVertexArrays(1, &g_cageEdgeVAO);
|
||||
|
||||
if (g_mesh)
|
||||
delete g_mesh;
|
||||
}
|
||||
@ -1037,14 +921,6 @@ keyboard(GLFWwindow *, int key, int /* scancode */, int event, int /* mods */) {
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
static void
|
||||
rebuildOsdMesh() {
|
||||
|
||||
createOsdMesh(g_defaultShapes[g_currentShape],
|
||||
g_level,
|
||||
g_defaultShapes[g_currentShape].scheme);
|
||||
}
|
||||
|
||||
static void
|
||||
callbackDisplayStyle(int b) {
|
||||
|
||||
@ -1055,7 +931,7 @@ static void
|
||||
callbackLevel(int l) {
|
||||
|
||||
g_level = l;
|
||||
rebuildOsdMesh();
|
||||
rebuildMesh();
|
||||
}
|
||||
|
||||
static void
|
||||
@ -1063,7 +939,7 @@ callbackModel(int m) {
|
||||
|
||||
int maxShapes = static_cast<int>(g_defaultShapes.size());
|
||||
g_currentShape = std::max(0, std::min(m, maxShapes-1));
|
||||
rebuildOsdMesh();
|
||||
rebuildMesh();
|
||||
}
|
||||
|
||||
static void
|
||||
@ -1071,7 +947,7 @@ callbackAdaptive(bool checked, int /* a */) {
|
||||
|
||||
if (GLUtils::SupportsAdaptiveTessellation()) {
|
||||
g_adaptive = checked;
|
||||
rebuildOsdMesh();
|
||||
rebuildMesh();
|
||||
}
|
||||
}
|
||||
|
||||
@ -1101,7 +977,7 @@ callbackBoundary(int b) {
|
||||
g_fvarBoundary = SdcOptions::FVAR_LINEAR_ALL; break;
|
||||
|
||||
}
|
||||
rebuildOsdMesh();
|
||||
rebuildMesh();
|
||||
}
|
||||
|
||||
static void
|
||||
@ -1166,10 +1042,6 @@ initGL() {
|
||||
glEnable(GL_CULL_FACE);
|
||||
|
||||
glGenVertexArrays(1, &g_vao);
|
||||
glGenVertexArrays(1, &g_cageVertexVAO);
|
||||
glGenVertexArrays(1, &g_cageEdgeVAO);
|
||||
glGenBuffers(1, &g_cageVertexVBO);
|
||||
glGenBuffers(1, &g_cageEdgeVBO);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
@ -1297,7 +1169,7 @@ int main(int argc, char ** argv) {
|
||||
glfwSwapInterval(0);
|
||||
|
||||
initHUD();
|
||||
rebuildOsdMesh();
|
||||
rebuildMesh();
|
||||
|
||||
while (g_running) {
|
||||
idle();
|
||||
|
@ -95,6 +95,7 @@ OpenSubdiv::Osd::GLMeshInterface *g_mesh;
|
||||
#include "../../regression/common/far_utils.h"
|
||||
#include "../common/stopwatch.h"
|
||||
#include "../common/simple_math.h"
|
||||
#include "../common/glControlMeshDisplay.h"
|
||||
#include "../common/glHud.h"
|
||||
#include "../common/glUtils.h"
|
||||
#include "../common/hdr_reader.h"
|
||||
@ -127,7 +128,7 @@ enum HudCheckBox { HUD_CB_ADAPTIVE,
|
||||
HUD_CB_DISPLAY_OCCLUSION,
|
||||
HUD_CB_DISPLAY_NORMALMAP,
|
||||
HUD_CB_DISPLAY_SPECULAR,
|
||||
HUD_CB_CAGE_EDGES,
|
||||
HUD_CB_CONTROL_MESH_EDGES,
|
||||
HUD_CB_ANIMATE_VERTICES,
|
||||
HUD_CB_VIEW_LOD,
|
||||
HUD_CB_FRACTIONAL_SPACING,
|
||||
@ -178,7 +179,6 @@ int g_frame = 0,
|
||||
int g_fullscreen = 0,
|
||||
g_wire = DISPLAY_SHADED,
|
||||
g_drawNormals = 0,
|
||||
g_drawCageEdges = 0,
|
||||
g_mbutton[3] = {0, 0, 0},
|
||||
g_level = 1,
|
||||
g_tessLevel = 2,
|
||||
@ -219,6 +219,7 @@ float g_rotate[2] = {0, 0},
|
||||
g_pan[2] = {0, 0},
|
||||
g_center[3] = {0, 0, 0},
|
||||
g_size = 0;
|
||||
float g_modelViewProjection[16];
|
||||
|
||||
int g_prev_x = 0,
|
||||
g_prev_y = 0;
|
||||
@ -228,6 +229,7 @@ int g_width = 1024,
|
||||
g_height = 1024;
|
||||
|
||||
GLhud g_hud;
|
||||
GLControlMeshDisplay g_controlMeshDisplay;
|
||||
|
||||
// performance
|
||||
float g_cpuTime = 0;
|
||||
@ -246,10 +248,8 @@ std::vector<std::vector<float> > g_animPositions;
|
||||
|
||||
GLuint g_queries[2] = {0, 0};
|
||||
GLuint g_vao = 0;
|
||||
GLuint g_cageEdgeVAO = 0;
|
||||
GLuint g_skyVAO = 0;
|
||||
GLuint g_edgeIndexBuffer = 0;
|
||||
GLuint g_numCageEdges = 0;
|
||||
|
||||
GLuint g_diffuseEnvironmentMap = 0;
|
||||
GLuint g_specularEnvironmentMap = 0;
|
||||
@ -886,8 +886,6 @@ createOsdMesh(int level, int kernel) {
|
||||
|
||||
g_positions=shape->verts;
|
||||
|
||||
typedef OpenSubdiv::Far::ConstIndexArray IndexArray;
|
||||
|
||||
// create Far mesh (topology)
|
||||
OpenSubdiv::Sdc::SchemeType sdctype = GetSdcType(*shape);
|
||||
OpenSubdiv::Sdc::Options sdcoptions = GetSdcOptions(*shape);
|
||||
@ -897,17 +895,7 @@ createOsdMesh(int level, int kernel) {
|
||||
OpenSubdiv::Far::TopologyRefinerFactory<Shape>::Options(sdctype, sdcoptions));
|
||||
|
||||
// save coarse topology (used for coarse mesh drawing)
|
||||
|
||||
// create cage edge index
|
||||
OpenSubdiv::Far::TopologyLevel const & refBaseLevel = refiner->GetLevel(0);
|
||||
|
||||
int nedges = refBaseLevel.GetNumEdges();
|
||||
std::vector<int> edgeIndices(nedges*2);
|
||||
for(int i=0; i<nedges; ++i) {
|
||||
IndexArray verts = refBaseLevel.GetEdgeVertices(i);
|
||||
edgeIndices[i*2 ]=verts[0];
|
||||
edgeIndices[i*2+1]=verts[1];
|
||||
}
|
||||
g_controlMeshDisplay.SetTopology(refiner->GetLevel(0));
|
||||
|
||||
delete shape;
|
||||
|
||||
@ -1036,24 +1024,6 @@ createOsdMesh(int level, int kernel) {
|
||||
}
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, g_mesh->GetPatchTable()->GetPatchIndexBuffer());
|
||||
|
||||
// ------ Cage VAO
|
||||
glBindVertexArray(g_cageEdgeVAO);
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, g_mesh->BindVertexBuffer());
|
||||
|
||||
if (g_adaptive) {
|
||||
glEnableVertexAttribArray(0);
|
||||
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);
|
||||
} else {
|
||||
glEnableVertexAttribArray(0);
|
||||
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 6, 0);
|
||||
}
|
||||
if (not g_edgeIndexBuffer) glGenBuffers(1, &g_edgeIndexBuffer);
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, g_edgeIndexBuffer);
|
||||
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(int)*edgeIndices.size(),
|
||||
&edgeIndices[0], GL_STATIC_DRAW);
|
||||
g_numCageEdges = (int)edgeIndices.size();
|
||||
|
||||
glBindVertexArray(0);
|
||||
}
|
||||
|
||||
@ -1148,6 +1118,9 @@ updateConstantUniformBlock() {
|
||||
constantData.ProjectionMatrix);
|
||||
inverseMatrix(constantData.ModelViewInverseMatrix,
|
||||
constantData.ModelViewMatrix);
|
||||
// save mvp for the control mesh drawing
|
||||
memcpy(g_modelViewProjection, constantData.ModelViewProjectionMatrix,
|
||||
16*sizeof(float));
|
||||
|
||||
// lighs
|
||||
Constant::Light light0 = { { 0.6f, 1.0f, 0.6f, 0.0f },
|
||||
@ -1362,34 +1335,6 @@ drawSky() {
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
void
|
||||
drawCageEdges() {
|
||||
|
||||
g_mesh->BindVertexBuffer();
|
||||
|
||||
glBindVertexArray(g_cageEdgeVAO);
|
||||
|
||||
Effect effect;
|
||||
effect.value = 0;
|
||||
|
||||
EffectDesc effectDesc(
|
||||
OpenSubdiv::Far::PatchDescriptor(
|
||||
OpenSubdiv::Far::PatchDescriptor::LINES), effect);
|
||||
|
||||
GLDrawConfig *config = g_shaderCache.GetDrawConfig(effectDesc);
|
||||
if (!config) return;
|
||||
|
||||
glUseProgram(config->GetProgram());
|
||||
glDrawElements(GL_LINES, g_numCageEdges, GL_UNSIGNED_INT, 0);
|
||||
|
||||
glBindVertexArray(0);
|
||||
glUseProgram(0);
|
||||
|
||||
GLUtils::CheckGLErrors("draw cage edges");
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
void
|
||||
display() {
|
||||
|
||||
@ -1427,8 +1372,13 @@ display() {
|
||||
glEndQuery(GL_TIME_ELAPSED);
|
||||
#endif
|
||||
|
||||
if (g_drawCageEdges)
|
||||
drawCageEdges();
|
||||
// draw the control mesh
|
||||
{
|
||||
GLuint vbo = g_mesh->BindVertexBuffer();
|
||||
int stride = g_adaptive ? 3 : 6;
|
||||
g_controlMeshDisplay.Draw(vbo, stride*sizeof(float),
|
||||
g_modelViewProjection);
|
||||
}
|
||||
|
||||
if (g_wire == DISPLAY_WIRE) {
|
||||
glEnable(GL_CULL_FACE);
|
||||
@ -1544,7 +1494,6 @@ void uninitGL() {
|
||||
|
||||
glDeleteQueries(2, g_queries);
|
||||
glDeleteVertexArrays(1, &g_vao);
|
||||
glDeleteVertexArrays(1, &g_cageEdgeVAO);
|
||||
glDeleteVertexArrays(1, &g_skyVAO);
|
||||
|
||||
if (g_mesh)
|
||||
@ -1627,8 +1576,8 @@ callbackCheckBox(bool checked, int button) {
|
||||
case HUD_CB_DISPLAY_SPECULAR:
|
||||
g_specular = checked;
|
||||
break;
|
||||
case HUD_CB_CAGE_EDGES:
|
||||
g_drawCageEdges = checked;
|
||||
case HUD_CB_CONTROL_MESH_EDGES:
|
||||
g_controlMeshDisplay.SetEdgesDisplay(checked);
|
||||
break;
|
||||
case HUD_CB_ANIMATE_VERTICES:
|
||||
g_moveScale = checked ? 1.0f : 0.0f;
|
||||
@ -1739,7 +1688,6 @@ initGL() {
|
||||
|
||||
glGenQueries(2, g_queries);
|
||||
glGenVertexArrays(1, &g_vao);
|
||||
glGenVertexArrays(1, &g_cageEdgeVAO);
|
||||
glGenVertexArrays(1, &g_skyVAO);
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
@ -1918,6 +1866,8 @@ int main(int argc, char ** argv) {
|
||||
|
||||
g_hud.SetFrameBuffer(new GLFrameBuffer);
|
||||
|
||||
g_controlMeshDisplay.SetEdgesDisplay(false);
|
||||
|
||||
if (occlusionFilename != NULL) {
|
||||
g_hud.AddCheckBox("Ambient Occlusion (A)", g_occlusion,
|
||||
-200, 570, callbackCheckBox, HUD_CB_DISPLAY_OCCLUSION, 'a');
|
||||
@ -1931,8 +1881,10 @@ int main(int argc, char ** argv) {
|
||||
-200, 610, callbackCheckBox, HUD_CB_IBL, 'i');
|
||||
}
|
||||
|
||||
g_hud.AddCheckBox("Cage Edges (H)", g_drawCageEdges != 0,
|
||||
10, 10, callbackCheckBox, HUD_CB_CAGE_EDGES, 'h');
|
||||
g_hud.AddCheckBox("Control edges (H)",
|
||||
g_controlMeshDisplay.GetEdgesDisplay(),
|
||||
10, 10, callbackCheckBox,
|
||||
HUD_CB_CONTROL_MESH_EDGES, 'h');
|
||||
g_hud.AddCheckBox("Animate vertices (M)", g_moveScale != 0.0,
|
||||
10, 30, callbackCheckBox, HUD_CB_ANIMATE_VERTICES, 'm');
|
||||
g_hud.AddCheckBox("Screen space LOD (V)", g_screenSpaceTess,
|
||||
|
@ -32,6 +32,7 @@ GLFWmonitor* g_primary=0;
|
||||
#include "../common/stopwatch.h"
|
||||
#include "../common/simple_math.h"
|
||||
#include "../common/glHud.h"
|
||||
#include "../common/glControlMeshDisplay.h"
|
||||
|
||||
#include <far/patchTableFactory.h>
|
||||
#include <far/ptexIndices.h>
|
||||
@ -97,6 +98,12 @@ enum KernelType { kCPU = 0,
|
||||
kGLXFB,
|
||||
kGLCompute };
|
||||
|
||||
enum HudCheckBox { kHUD_CB_DISPLAY_CONTROL_MESH_EDGES,
|
||||
kHUD_CB_DISPLAY_CONTROL_MESH_VERTS,
|
||||
kHUD_CB_ANIMATE_VERTICES,
|
||||
kHUD_CB_FREEZE,
|
||||
kHUD_CB_BILINEAR };
|
||||
|
||||
int g_kernel = kCPU,
|
||||
g_isolationLevel = 5; // max level of extraordinary feature isolation
|
||||
|
||||
@ -104,8 +111,6 @@ int g_running = 1,
|
||||
g_width = 1024,
|
||||
g_height = 1024,
|
||||
g_fullscreen = 0,
|
||||
g_drawCageEdges = 1,
|
||||
g_drawCageVertices = 1,
|
||||
g_prev_x = 0,
|
||||
g_prev_y = 0,
|
||||
g_mbutton[3] = {0, 0, 0},
|
||||
@ -136,21 +141,13 @@ Stopwatch g_fpsTimer;
|
||||
std::vector<float> g_orgPositions;
|
||||
std::vector<float> g_positions;
|
||||
|
||||
std::vector<int> g_coarseEdges;
|
||||
std::vector<float> g_coarseEdgeSharpness;
|
||||
std::vector<float> g_coarseVertexSharpness;
|
||||
|
||||
int g_nsamples=2000,
|
||||
g_nsamplesDrawn=0;
|
||||
|
||||
GLuint g_cageEdgeVAO = 0,
|
||||
g_cageEdgeVBO = 0,
|
||||
g_cageVertexVAO = 0,
|
||||
g_cageVertexVBO = 0,
|
||||
g_stencilsVAO = 0;
|
||||
GLuint g_stencilsVAO = 0;
|
||||
|
||||
GLhud g_hud;
|
||||
|
||||
GLControlMeshDisplay g_controlMeshDisplay;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
@ -166,6 +163,7 @@ public:
|
||||
virtual ~StencilOutputBase() {}
|
||||
virtual void UpdateData(const float *src, int startVertex, int numVertices) = 0;
|
||||
virtual void EvalStencils() = 0;
|
||||
virtual GLuint BindSrcBuffer() = 0;
|
||||
virtual GLuint BindDstBuffer() = 0;
|
||||
virtual int GetNumStencils() const = 0;
|
||||
};
|
||||
@ -223,6 +221,9 @@ public:
|
||||
evalInstance,
|
||||
_deviceContext);
|
||||
}
|
||||
virtual GLuint BindSrcBuffer() {
|
||||
return _srcData->BindVBO();
|
||||
}
|
||||
virtual GLuint BindDstBuffer() {
|
||||
return _dstData->BindVBO();
|
||||
}
|
||||
@ -288,7 +289,6 @@ updateGeom() {
|
||||
static void
|
||||
createMesh(ShapeDesc const & shapeDesc, int level) {
|
||||
|
||||
typedef Far::ConstIndexArray IndexArray;
|
||||
typedef Far::LimitStencilTableFactory::LocationArray LocationArray;
|
||||
|
||||
Shape const * shape = Shape::parseObj(shapeDesc.data.c_str(), shapeDesc.scheme);
|
||||
@ -304,25 +304,11 @@ createMesh(ShapeDesc const & shapeDesc, int level) {
|
||||
// save coarse topology (used for coarse mesh drawing)
|
||||
OpenSubdiv::Far::TopologyLevel const & refBaseLevel = refiner->GetLevel(0);
|
||||
|
||||
int nedges = refBaseLevel.GetNumEdges(),
|
||||
nverts = refBaseLevel.GetNumVertices();
|
||||
g_controlMeshDisplay.SetTopology(refBaseLevel);
|
||||
int nverts = refBaseLevel.GetNumVertices();
|
||||
|
||||
g_coarseEdges.resize(nedges*2);
|
||||
g_coarseEdgeSharpness.resize(nedges);
|
||||
g_coarseVertexSharpness.resize(nverts);
|
||||
|
||||
for(int i=0; i<nedges; ++i) {
|
||||
IndexArray verts = refBaseLevel.GetEdgeVertices(i);
|
||||
g_coarseEdges[i*2 ]=verts[0];
|
||||
g_coarseEdges[i*2+1]=verts[1];
|
||||
g_coarseEdgeSharpness[i]=refBaseLevel.GetEdgeSharpness(i);
|
||||
}
|
||||
|
||||
for(int i=0; i<nverts; ++i) {
|
||||
g_coarseVertexSharpness[i]=refBaseLevel.GetVertexSharpness(i);
|
||||
}
|
||||
|
||||
g_orgPositions=shape->verts;
|
||||
// save rest pose
|
||||
g_orgPositions = shape->verts;
|
||||
|
||||
if (g_bilinear) {
|
||||
Far::TopologyRefiner::UniformOptions options(level);
|
||||
@ -370,14 +356,14 @@ createMesh(ShapeDesc const & shapeDesc, int level) {
|
||||
|
||||
delete g_stencilOutput;
|
||||
if (g_kernel == kCPU) {
|
||||
g_stencilOutput = new StencilOutput<Osd::CpuVertexBuffer,
|
||||
g_stencilOutput = new StencilOutput<Osd::CpuGLVertexBuffer,
|
||||
Osd::CpuGLVertexBuffer,
|
||||
Far::LimitStencilTable,
|
||||
Osd::CpuEvaluator>(
|
||||
g_controlStencils, nverts);
|
||||
#ifdef OPENSUBDIV_HAS_OPENMP
|
||||
} else if (g_kernel == kOPENMP) {
|
||||
g_stencilOutput = new StencilOutput<Osd::CpuVertexBuffer,
|
||||
g_stencilOutput = new StencilOutput<Osd::CpuGLVertexBuffer,
|
||||
Osd::CpuGLVertexBuffer,
|
||||
Far::LimitStencilTable,
|
||||
Osd::OmpEvaluator>(
|
||||
@ -385,7 +371,7 @@ createMesh(ShapeDesc const & shapeDesc, int level) {
|
||||
#endif
|
||||
#ifdef OPENSUBDIV_HAS_TBB
|
||||
} else if (g_kernel == kTBB) {
|
||||
g_stencilOutput = new StencilOutput<Osd::CpuVertexBuffer,
|
||||
g_stencilOutput = new StencilOutput<Osd::CpuGLVertexBuffer,
|
||||
Osd::CpuGLVertexBuffer,
|
||||
Far::LimitStencilTable,
|
||||
Osd::TbbEvaluator>(
|
||||
@ -393,7 +379,7 @@ createMesh(ShapeDesc const & shapeDesc, int level) {
|
||||
#endif
|
||||
#ifdef OPENSUBDIV_HAS_CUDA
|
||||
} else if (g_kernel == kCUDA) {
|
||||
g_stencilOutput = new StencilOutput<Osd::CudaVertexBuffer,
|
||||
g_stencilOutput = new StencilOutput<Osd::CudaGLVertexBuffer,
|
||||
Osd::CudaGLVertexBuffer,
|
||||
Osd::CudaStencilTable,
|
||||
Osd::CudaEvaluator>(
|
||||
@ -402,7 +388,7 @@ createMesh(ShapeDesc const & shapeDesc, int level) {
|
||||
#ifdef OPENSUBDIV_HAS_OPENCL
|
||||
} else if (g_kernel == kCL) {
|
||||
static Osd::EvaluatorCacheT<Osd::CLEvaluator> clEvaluatorCache;
|
||||
g_stencilOutput = new StencilOutput<Osd::CLVertexBuffer,
|
||||
g_stencilOutput = new StencilOutput<Osd::CLGLVertexBuffer,
|
||||
Osd::CLGLVertexBuffer,
|
||||
Osd::CLStencilTable,
|
||||
Osd::CLEvaluator,
|
||||
@ -571,8 +557,7 @@ private:
|
||||
|
||||
};
|
||||
|
||||
GLSLProgram g_cageProgram,
|
||||
g_samplesProgram;
|
||||
GLSLProgram g_samplesProgram;
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
@ -584,35 +569,6 @@ linkDefaultPrograms() {
|
||||
#else
|
||||
#define GLSL_VERSION_DEFINE "#version 150\n"
|
||||
#endif
|
||||
|
||||
{ // setup control cage program
|
||||
static const char *vsSrc =
|
||||
GLSL_VERSION_DEFINE
|
||||
"in vec3 position;\n"
|
||||
"in vec3 color;\n"
|
||||
"out vec4 fragColor;\n"
|
||||
"uniform mat4 ModelViewProjectionMatrix;\n"
|
||||
"void main() {\n"
|
||||
" fragColor = vec4(color, 1);\n"
|
||||
" gl_Position = ModelViewProjectionMatrix * "
|
||||
" vec4(position, 1);\n"
|
||||
"}\n";
|
||||
|
||||
static const char *fsSrc =
|
||||
GLSL_VERSION_DEFINE
|
||||
"in vec4 fragColor;\n"
|
||||
"out vec4 color;\n"
|
||||
"void main() {\n"
|
||||
" color = fragColor;\n"
|
||||
"}\n";
|
||||
|
||||
g_cageProgram.SetVertexShaderSource(vsSrc);
|
||||
g_cageProgram.SetFragShaderSource(fsSrc);
|
||||
|
||||
g_cageProgram.AddAttribute( "position",3 );
|
||||
g_cageProgram.AddAttribute( "color",3 );
|
||||
}
|
||||
|
||||
{ // setup samples program
|
||||
//
|
||||
// this shader takes position, uTangent and vTangent for each point
|
||||
@ -693,97 +649,6 @@ linkDefaultPrograms() {
|
||||
|
||||
return true;
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
static inline void
|
||||
setSharpnessColor(float s, float *r, float *g, float *b) {
|
||||
|
||||
// 0.0 2.0 4.0
|
||||
// green --- yellow --- red
|
||||
*r = std::min(1.0f, s * 0.5f);
|
||||
*g = std::min(1.0f, 2.0f - s*0.5f);
|
||||
*b = 0;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
static void
|
||||
drawCageEdges() {
|
||||
|
||||
g_cageProgram.Use( );
|
||||
|
||||
glUniformMatrix4fv(g_cageProgram.GetUniformModelViewProjectionMatrix(),
|
||||
1, GL_FALSE, g_transformData.ModelViewProjectionMatrix);
|
||||
|
||||
std::vector<float> vbo;
|
||||
vbo.reserve(g_coarseEdges.size() * 6);
|
||||
|
||||
float r, g, b;
|
||||
for (int i = 0; i < (int)g_coarseEdges.size(); i+=2) {
|
||||
setSharpnessColor(g_coarseEdgeSharpness[i/2], &r, &g, &b);
|
||||
for (int j = 0; j < 2; ++j) {
|
||||
vbo.push_back(g_positions[g_coarseEdges[i+j]*3]);
|
||||
vbo.push_back(g_positions[g_coarseEdges[i+j]*3+1]);
|
||||
vbo.push_back(g_positions[g_coarseEdges[i+j]*3+2]);
|
||||
vbo.push_back(r);
|
||||
vbo.push_back(g);
|
||||
vbo.push_back(b);
|
||||
}
|
||||
}
|
||||
|
||||
glBindVertexArray(g_cageEdgeVAO);
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, g_cageEdgeVBO);
|
||||
glBufferData(GL_ARRAY_BUFFER, (int)vbo.size() * sizeof(float), &vbo[0],
|
||||
GL_STATIC_DRAW);
|
||||
|
||||
g_cageProgram.EnableVertexAttributes();
|
||||
|
||||
glDrawArrays(GL_LINES, 0, (int)g_coarseEdges.size());
|
||||
|
||||
glBindVertexArray(0);
|
||||
glUseProgram(0);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
static void
|
||||
drawCageVertices() {
|
||||
|
||||
g_cageProgram.Use( );
|
||||
|
||||
glUniformMatrix4fv(g_cageProgram.GetUniformModelViewProjectionMatrix(),
|
||||
1, GL_FALSE, g_transformData.ModelViewProjectionMatrix);
|
||||
|
||||
int numPoints = (int)g_positions.size()/3;
|
||||
std::vector<float> vbo;
|
||||
vbo.reserve(numPoints*6);
|
||||
|
||||
float r, g, b;
|
||||
for (int i = 0; i < numPoints; ++i) {
|
||||
|
||||
setSharpnessColor(g_coarseVertexSharpness[i], &r, &g, &b);
|
||||
|
||||
vbo.push_back(g_positions[i*3+0]);
|
||||
vbo.push_back(g_positions[i*3+1]);
|
||||
vbo.push_back(g_positions[i*3+2]);
|
||||
vbo.push_back(r);
|
||||
vbo.push_back(g);
|
||||
vbo.push_back(b);
|
||||
}
|
||||
|
||||
glBindVertexArray(g_cageVertexVAO);
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, g_cageVertexVBO);
|
||||
glBufferData(GL_ARRAY_BUFFER, (int)vbo.size() * sizeof(float), &vbo[0],
|
||||
GL_STATIC_DRAW);
|
||||
|
||||
g_cageProgram.EnableVertexAttributes();
|
||||
|
||||
glPointSize(10.0f);
|
||||
glDrawArrays(GL_POINTS, 0, numPoints);
|
||||
glPointSize(1.0f);
|
||||
|
||||
glBindVertexArray(0);
|
||||
glUseProgram(0);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
static void
|
||||
@ -801,9 +666,6 @@ drawStencils() {
|
||||
|
||||
glBindVertexArray(g_stencilsVAO);
|
||||
|
||||
// int numEdges = g_controlStencils->GetNumStencils() * 3;
|
||||
// g_samplesProgram.EnableVertexAttributes();
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, g_stencilOutput->BindDstBuffer());
|
||||
|
||||
glEnableVertexAttribArray(0);
|
||||
@ -813,8 +675,6 @@ drawStencils() {
|
||||
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(GLfloat)*9, (void*)(sizeof(GLfloat)*3));
|
||||
glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, sizeof(GLfloat)*9, (void*)(sizeof(GLfloat)*6));
|
||||
|
||||
// g_samplesProgram.EnableVertexAttributes();
|
||||
|
||||
glDrawArrays(GL_POINTS, 0, g_stencilOutput->GetNumStencils());
|
||||
|
||||
glDisableVertexAttribArray(0);
|
||||
@ -854,13 +714,12 @@ display() {
|
||||
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
|
||||
if (g_drawCageEdges)
|
||||
drawCageEdges();
|
||||
|
||||
if (g_drawCageVertices)
|
||||
drawCageVertices();
|
||||
|
||||
drawStencils();
|
||||
|
||||
// draw the control mesh
|
||||
g_controlMeshDisplay.Draw(g_stencilOutput->BindSrcBuffer(), 3*sizeof(float),
|
||||
g_transformData.ModelViewProjectionMatrix);
|
||||
|
||||
s.Stop();
|
||||
float drawCpuTime = float(s.GetElapsed() * 1000.0f);
|
||||
s.Start();
|
||||
@ -1028,41 +887,6 @@ callbackLevel(int l) {
|
||||
rebuildMesh();
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
static void
|
||||
callbackAnimate(bool checked, int /* m */) {
|
||||
|
||||
g_moveScale = checked;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
static void
|
||||
callbackFreeze(bool checked, int /* f */) {
|
||||
|
||||
g_freeze = checked;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
static void
|
||||
callbackDisplayCageVertices(bool checked, int /* d */) {
|
||||
|
||||
g_drawCageVertices = checked;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
static void
|
||||
callbackDisplayCageEdges(bool checked, int /* d */) {
|
||||
g_drawCageEdges = checked;
|
||||
}
|
||||
|
||||
static void
|
||||
callbackBilinear(bool checked, int /* a */) {
|
||||
g_bilinear = checked;
|
||||
rebuildMesh();
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
static void
|
||||
callbackModel(int m) {
|
||||
@ -1078,6 +902,28 @@ callbackModel(int m) {
|
||||
rebuildMesh();
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
static void
|
||||
callbackCheckBox(bool checked, int button) {
|
||||
switch (button) {
|
||||
case kHUD_CB_DISPLAY_CONTROL_MESH_EDGES:
|
||||
g_controlMeshDisplay.SetEdgesDisplay(checked);
|
||||
break;
|
||||
case kHUD_CB_DISPLAY_CONTROL_MESH_VERTS:
|
||||
g_controlMeshDisplay.SetVerticesDisplay(checked);
|
||||
break;
|
||||
case kHUD_CB_ANIMATE_VERTICES:
|
||||
g_moveScale = checked;
|
||||
break;
|
||||
case kHUD_CB_FREEZE:
|
||||
g_freeze = checked;
|
||||
break;
|
||||
case kHUD_CB_BILINEAR:
|
||||
g_bilinear = checked;
|
||||
rebuildMesh();
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
static void
|
||||
initHUD() {
|
||||
@ -1093,12 +939,20 @@ initHUD() {
|
||||
|
||||
g_hud.SetFrameBuffer(new GLFrameBuffer);
|
||||
|
||||
g_hud.AddCheckBox("Cage Edges (H)", true, 10, 10, callbackDisplayCageEdges, 0, 'h');
|
||||
g_hud.AddCheckBox("Cage Verts (J)", true, 10, 30, callbackDisplayCageVertices, 0, 'j');
|
||||
g_hud.AddCheckBox("Animate vertices (M)", g_moveScale != 0, 10, 50, callbackAnimate, 0, 'm');
|
||||
g_hud.AddCheckBox("Freeze (spc)", false, 10, 70, callbackFreeze, 0, ' ');
|
||||
|
||||
g_hud.AddCheckBox("Bilinear Stencils (`)", g_bilinear!=0, 10, 190, callbackBilinear, 0, '`');
|
||||
g_hud.AddCheckBox("Control edges (H)",
|
||||
g_controlMeshDisplay.GetEdgesDisplay(),
|
||||
10, 10, callbackCheckBox,
|
||||
kHUD_CB_DISPLAY_CONTROL_MESH_EDGES, 'h');
|
||||
g_hud.AddCheckBox("Control vertices (J)",
|
||||
g_controlMeshDisplay.GetVerticesDisplay(),
|
||||
10, 30, callbackCheckBox,
|
||||
kHUD_CB_DISPLAY_CONTROL_MESH_VERTS, 'j');
|
||||
g_hud.AddCheckBox("Animate vertices (M)", g_moveScale != 0,
|
||||
10, 50, callbackCheckBox, kHUD_CB_ANIMATE_VERTICES, 'm');
|
||||
g_hud.AddCheckBox("Freeze (spc)", g_freeze != 0,
|
||||
10, 70, callbackCheckBox, kHUD_CB_FREEZE, ' ');
|
||||
g_hud.AddCheckBox("Bilinear Stencils (`)", g_bilinear != 0,
|
||||
10, 190, callbackCheckBox, kHUD_CB_BILINEAR, '`');
|
||||
|
||||
int compute_pulldown = g_hud.AddPullDown("Compute (K)", 250, 10, 300, callbackKernel, 'k');
|
||||
g_hud.AddPullDownButton(compute_pulldown, "CPU", kCPU);
|
||||
@ -1145,23 +999,12 @@ initGL() {
|
||||
glCullFace(GL_BACK);
|
||||
glEnable(GL_CULL_FACE);
|
||||
|
||||
glGenVertexArrays(1, &g_cageVertexVAO);
|
||||
glGenVertexArrays(1, &g_cageEdgeVAO);
|
||||
glGenVertexArrays(1, &g_stencilsVAO);
|
||||
|
||||
glGenBuffers(1, &g_cageVertexVBO);
|
||||
glGenBuffers(1, &g_cageEdgeVBO);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
static void
|
||||
uninitGL() {
|
||||
|
||||
glDeleteBuffers(1, &g_cageVertexVBO);
|
||||
glDeleteBuffers(1, &g_cageEdgeVBO);
|
||||
|
||||
glDeleteVertexArrays(1, &g_cageVertexVAO);
|
||||
glDeleteVertexArrays(1, &g_cageEdgeVAO);
|
||||
glDeleteVertexArrays(1, &g_stencilsVAO);
|
||||
}
|
||||
|
||||
|
@ -73,15 +73,18 @@ OpenSubdiv::Osd::GLMeshInterface *g_mesh = NULL;
|
||||
OpenSubdiv::Osd::GLLegacyGregoryPatchTable *g_legacyGregoryPatchTable = NULL;
|
||||
|
||||
#include "../../regression/common/far_utils.h"
|
||||
#include "../common/stopwatch.h"
|
||||
#include "../common/simple_math.h"
|
||||
#include "../common/glHud.h"
|
||||
#include "../common/glUtils.h"
|
||||
#include "../common/glControlMeshDisplay.h"
|
||||
#include "../common/glShaderCache.h"
|
||||
#include "../common/objAnim.h"
|
||||
#include "../common/patchColors.h"
|
||||
#include "../common/glShaderCache.h"
|
||||
#include "../common/simple_math.h"
|
||||
#include "../common/stopwatch.h"
|
||||
#include <osd/glslPatchShaderSource.h>
|
||||
|
||||
|
||||
|
||||
/* Function to get the correct shader file based on the opengl version.
|
||||
The implentation varies depending if glew is available or not. In case
|
||||
is available the capabilities are queried during execution and the correct
|
||||
@ -145,8 +148,8 @@ enum EndCap { kEndCapNone = 0,
|
||||
kEndCapGregoryBasis,
|
||||
kEndCapLegacyGregory };
|
||||
|
||||
enum HudCheckBox { kHUD_CB_DISPLAY_CAGE_EDGES,
|
||||
kHUD_CB_DISPLAY_CAGE_VERTS,
|
||||
enum HudCheckBox { kHUD_CB_DISPLAY_CONTROL_MESH_EDGES,
|
||||
kHUD_CB_DISPLAY_CONTROL_MESH_VERTS,
|
||||
kHUD_CB_ANIMATE_VERTICES,
|
||||
kHUD_CB_DISPLAY_PATCH_COLOR,
|
||||
kHUD_CB_VIEW_LOD,
|
||||
@ -174,8 +177,6 @@ int g_fullscreen = 0,
|
||||
g_adaptive = 1,
|
||||
g_endCap = kEndCapBSplineBasis,
|
||||
g_singleCreasePatch = 1,
|
||||
g_drawCageEdges = 1,
|
||||
g_drawCageVertices = 0,
|
||||
g_mbutton[3] = {0, 0, 0},
|
||||
g_running = 1;
|
||||
|
||||
@ -198,6 +199,7 @@ int g_width = 1024,
|
||||
g_height = 1024;
|
||||
|
||||
GLhud g_hud;
|
||||
GLControlMeshDisplay g_controlMeshDisplay;
|
||||
|
||||
// performance
|
||||
float g_cpuTime = 0;
|
||||
@ -205,10 +207,7 @@ float g_gpuTime = 0;
|
||||
Stopwatch g_fpsTimer;
|
||||
|
||||
// geometry
|
||||
std::vector<float> g_orgPositions,
|
||||
g_positions;
|
||||
|
||||
Scheme g_scheme;
|
||||
std::vector<float> g_orgPositions;
|
||||
|
||||
int g_level = 2;
|
||||
int g_tessLevel = 1;
|
||||
@ -232,23 +231,6 @@ struct Transform {
|
||||
} g_transformData;
|
||||
|
||||
GLuint g_vao = 0;
|
||||
GLuint g_cageEdgeVAO = 0,
|
||||
g_cageEdgeVBO = 0,
|
||||
g_cageVertexVAO = 0,
|
||||
g_cageVertexVBO = 0;
|
||||
|
||||
std::vector<int> g_coarseEdges;
|
||||
std::vector<float> g_coarseEdgeSharpness;
|
||||
std::vector<float> g_coarseVertexSharpness;
|
||||
|
||||
struct Program
|
||||
{
|
||||
GLuint program;
|
||||
GLuint uniformModelViewProjectionMatrix;
|
||||
GLuint attrPosition;
|
||||
GLuint attrColor;
|
||||
} g_defaultProgram;
|
||||
|
||||
|
||||
// XXX:
|
||||
// this struct meant to be used as a stopgap entity until we fully implement
|
||||
@ -300,62 +282,6 @@ struct FVarData
|
||||
GLuint textureBuffer;
|
||||
} g_fvarData;
|
||||
|
||||
static bool
|
||||
linkDefaultProgram() {
|
||||
|
||||
const std::string glsl_version = GLUtils::GetShaderVersionInclude();
|
||||
|
||||
|
||||
static const std::string vsSrc =
|
||||
glsl_version +
|
||||
"in vec3 position;\n"
|
||||
"in vec3 color;\n"
|
||||
"out vec4 fragColor;\n"
|
||||
"uniform mat4 ModelViewProjectionMatrix;\n"
|
||||
"void main() {\n"
|
||||
" fragColor = vec4(color, 1);\n"
|
||||
" gl_Position = ModelViewProjectionMatrix * "
|
||||
" vec4(position, 1);\n"
|
||||
"}\n";
|
||||
|
||||
static const std::string fsSrc =
|
||||
glsl_version +
|
||||
"in vec4 fragColor;\n"
|
||||
"out vec4 color;\n"
|
||||
"void main() {\n"
|
||||
" color = fragColor;\n"
|
||||
"}\n";
|
||||
|
||||
GLuint program = glCreateProgram();
|
||||
GLuint vertexShader = GLUtils::CompileShader(GL_VERTEX_SHADER, vsSrc.c_str());
|
||||
GLuint fragmentShader = GLUtils::CompileShader(GL_FRAGMENT_SHADER, fsSrc.c_str());
|
||||
|
||||
glAttachShader(program, vertexShader);
|
||||
glAttachShader(program, fragmentShader);
|
||||
|
||||
glLinkProgram(program);
|
||||
|
||||
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);
|
||||
printf("%s\n", infoLog);
|
||||
delete[] infoLog;
|
||||
exit(1);
|
||||
}
|
||||
|
||||
g_defaultProgram.program = program;
|
||||
g_defaultProgram.uniformModelViewProjectionMatrix =
|
||||
glGetUniformLocation(program, "ModelViewProjectionMatrix");
|
||||
g_defaultProgram.attrPosition = glGetAttribLocation(program, "position");
|
||||
g_defaultProgram.attrColor = glGetAttribLocation(program, "color");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
#include "init_shapes.h"
|
||||
@ -380,16 +306,6 @@ updateGeom() {
|
||||
|
||||
g_objAnim->InterpolatePositions(g_animTime, &vertex[0], stride);
|
||||
|
||||
if (g_drawCageEdges or g_drawCageVertices) {
|
||||
g_positions.resize(nverts*3);
|
||||
for (int i=0; i<nverts; ++i) {
|
||||
int ofs = i * stride;
|
||||
g_positions[i*3+0] = vertex[ofs+0];
|
||||
g_positions[i*3+1] = vertex[ofs+1];
|
||||
g_positions[i*3+2] = vertex[ofs+2];
|
||||
}
|
||||
}
|
||||
|
||||
if (g_displayStyle == kVaryingColor or
|
||||
g_displayStyle == kInterleavedVaryingColor) {
|
||||
|
||||
@ -423,40 +339,25 @@ updateGeom() {
|
||||
}
|
||||
|
||||
const float *p = &g_orgPositions[0];
|
||||
|
||||
float r = sin(g_frame*0.001f) * g_moveScale;
|
||||
for (int i = 0; i < nverts; ++i) {
|
||||
//float move = 0.05f*cosf(p[0]*20+g_frame*0.01f);
|
||||
float ct = cos(p[2] * r);
|
||||
float st = sin(p[2] * r);
|
||||
g_positions[i*3+0] = p[0]*ct + p[1]*st;
|
||||
g_positions[i*3+1] = -p[0]*st + p[1]*ct;
|
||||
g_positions[i*3+2] = p[2];
|
||||
|
||||
p += 3;
|
||||
}
|
||||
|
||||
p = &g_orgPositions[0];
|
||||
const float *pp = &g_positions[0];
|
||||
for (int i = 0; i < nverts; ++i) {
|
||||
vertex.push_back(pp[0]);
|
||||
vertex.push_back(pp[1]);
|
||||
vertex.push_back(pp[2]);
|
||||
vertex.push_back( p[0]*ct + p[1]*st);
|
||||
vertex.push_back(-p[0]*st + p[1]*ct);
|
||||
vertex.push_back( p[2]);
|
||||
if (g_displayStyle == kInterleavedVaryingColor) {
|
||||
vertex.push_back(p[1]);
|
||||
vertex.push_back(p[2]);
|
||||
vertex.push_back(p[0]);
|
||||
vertex.push_back(1.0f);
|
||||
p += 3;
|
||||
}
|
||||
if (g_displayStyle == kVaryingColor) {
|
||||
} else if (g_displayStyle == kVaryingColor) {
|
||||
varying.push_back(p[2]);
|
||||
varying.push_back(p[1]);
|
||||
varying.push_back(p[0]);
|
||||
varying.push_back(1);
|
||||
p += 3;
|
||||
}
|
||||
pp += 3;
|
||||
p += 3;
|
||||
}
|
||||
}
|
||||
|
||||
@ -503,18 +404,21 @@ getKernelName(int kernel) {
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
static void
|
||||
createOsdMesh(ShapeDesc const & shapeDesc, int level, int kernel, Scheme scheme=kCatmark) {
|
||||
|
||||
rebuildMesh() {
|
||||
using namespace OpenSubdiv;
|
||||
typedef Far::ConstIndexArray IndexArray;
|
||||
|
||||
ShapeDesc const &shapeDesc = g_defaultShapes[g_currentShape];
|
||||
int level = g_level;
|
||||
int kernel = g_kernel;
|
||||
bool doAnim = g_objAnim and g_currentShape==0;
|
||||
Scheme scheme = shapeDesc.scheme;
|
||||
|
||||
Shape const * shape = 0;
|
||||
if (doAnim) {
|
||||
shape = g_objAnim->GetShape();
|
||||
} else {
|
||||
shape = Shape::parseObj(shapeDesc.data.c_str(), shapeDesc.scheme, shapeDesc.isLeftHanded);
|
||||
shape = Shape::parseObj(shapeDesc.data.c_str(), shapeDesc.scheme,
|
||||
shapeDesc.isLeftHanded);
|
||||
}
|
||||
|
||||
// create Far mesh (topology)
|
||||
@ -526,39 +430,17 @@ createOsdMesh(ShapeDesc const & shapeDesc, int level, int kernel, Scheme scheme=
|
||||
Far::TopologyRefinerFactory<Shape>::Options(sdctype, sdcoptions));
|
||||
|
||||
// save coarse topology (used for coarse mesh drawing)
|
||||
OpenSubdiv::Far::TopologyLevel const & refBaseLevel = refiner->GetLevel(0);
|
||||
g_controlMeshDisplay.SetTopology(refiner->GetLevel(0));
|
||||
|
||||
int nedges = refBaseLevel.GetNumEdges(),
|
||||
nverts = refBaseLevel.GetNumVertices();
|
||||
|
||||
g_coarseEdges.resize(nedges*2);
|
||||
g_coarseEdgeSharpness.resize(nedges);
|
||||
g_coarseVertexSharpness.resize(nverts);
|
||||
|
||||
for(int i=0; i<nedges; ++i) {
|
||||
IndexArray verts = refBaseLevel.GetEdgeVertices(i);
|
||||
g_coarseEdges[i*2 ]=verts[0];
|
||||
g_coarseEdges[i*2+1]=verts[1];
|
||||
g_coarseEdgeSharpness[i]=refBaseLevel.GetEdgeSharpness(i);
|
||||
}
|
||||
|
||||
for(int i=0; i<nverts; ++i) {
|
||||
g_coarseVertexSharpness[i]=refBaseLevel.GetVertexSharpness(i);
|
||||
}
|
||||
|
||||
g_orgPositions=shape->verts;
|
||||
|
||||
g_positions.resize(g_orgPositions.size(),0.0f);
|
||||
g_orgPositions = shape->verts;
|
||||
|
||||
delete g_mesh;
|
||||
g_mesh = NULL;
|
||||
|
||||
g_scheme = scheme;
|
||||
|
||||
// Adaptive refinement currently supported only for catmull-clark scheme
|
||||
bool doAdaptive = (g_adaptive!=0 and g_scheme==kCatmark),
|
||||
bool doAdaptive = (g_adaptive!=0 and scheme==kCatmark),
|
||||
interleaveVarying = g_displayStyle == kInterleavedVaryingColor,
|
||||
doSingleCreasePatch = (g_singleCreasePatch!=0 and g_scheme==kCatmark);
|
||||
doSingleCreasePatch = (g_singleCreasePatch!=0 and scheme==kCatmark);
|
||||
|
||||
Osd::MeshBitset bits;
|
||||
bits.set(Osd::MeshAdaptive, doAdaptive);
|
||||
@ -573,6 +455,7 @@ createOsdMesh(ShapeDesc const & shapeDesc, int level, int kernel, Scheme scheme=
|
||||
int numVaryingElements =
|
||||
(g_displayStyle == kVaryingColor or interleaveVarying) ? 4 : 0;
|
||||
|
||||
|
||||
if (kernel == kCPU) {
|
||||
g_mesh = new Osd::Mesh<Osd::CpuGLVertexBuffer,
|
||||
Far::StencilTable,
|
||||
@ -743,99 +626,6 @@ fitFrame() {
|
||||
g_dolly = g_size;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
static inline void
|
||||
setSharpnessColor(float s, float *r, float *g, float *b) {
|
||||
// 0.0 2.0 4.0
|
||||
// green --- yellow --- red
|
||||
*r = std::min(1.0f, s * 0.5f);
|
||||
*g = std::min(1.0f, 2.0f - s*0.5f);
|
||||
*b = 0;
|
||||
}
|
||||
|
||||
static void
|
||||
drawCageEdges() {
|
||||
|
||||
glUseProgram(g_defaultProgram.program);
|
||||
glUniformMatrix4fv(g_defaultProgram.uniformModelViewProjectionMatrix,
|
||||
1, GL_FALSE, g_transformData.ModelViewProjectionMatrix);
|
||||
|
||||
std::vector<float> vbo;
|
||||
vbo.reserve(g_coarseEdges.size() * 6);
|
||||
float r, g, b;
|
||||
for (int i = 0; i < (int)g_coarseEdges.size(); i+=2) {
|
||||
setSharpnessColor(g_coarseEdgeSharpness[i/2], &r, &g, &b);
|
||||
for (int j = 0; j < 2; ++j) {
|
||||
vbo.push_back(g_positions[g_coarseEdges[i+j]*3]);
|
||||
vbo.push_back(g_positions[g_coarseEdges[i+j]*3+1]);
|
||||
vbo.push_back(g_positions[g_coarseEdges[i+j]*3+2]);
|
||||
vbo.push_back(r);
|
||||
vbo.push_back(g);
|
||||
vbo.push_back(b);
|
||||
}
|
||||
}
|
||||
|
||||
glBindVertexArray(g_cageEdgeVAO);
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, g_cageEdgeVBO);
|
||||
glBufferData(GL_ARRAY_BUFFER, (int)vbo.size() * sizeof(float), &vbo[0],
|
||||
GL_STATIC_DRAW);
|
||||
|
||||
glEnableVertexAttribArray(g_defaultProgram.attrPosition);
|
||||
glEnableVertexAttribArray(g_defaultProgram.attrColor);
|
||||
glVertexAttribPointer(g_defaultProgram.attrPosition,
|
||||
3, GL_FLOAT, GL_FALSE, sizeof (GLfloat) * 6, 0);
|
||||
glVertexAttribPointer(g_defaultProgram.attrColor,
|
||||
3, GL_FLOAT, GL_FALSE, sizeof (GLfloat) * 6, (void*)12);
|
||||
|
||||
glDrawArrays(GL_LINES, 0, (int)g_coarseEdges.size());
|
||||
|
||||
glBindVertexArray(0);
|
||||
glUseProgram(0);
|
||||
}
|
||||
|
||||
static void
|
||||
drawCageVertices() {
|
||||
|
||||
glUseProgram(g_defaultProgram.program);
|
||||
glUniformMatrix4fv(g_defaultProgram.uniformModelViewProjectionMatrix,
|
||||
1, GL_FALSE, g_transformData.ModelViewProjectionMatrix);
|
||||
|
||||
int numPoints = (int)g_positions.size()/3;
|
||||
std::vector<float> vbo;
|
||||
vbo.reserve(numPoints*6);
|
||||
float r, g, b;
|
||||
for (int i = 0; i < numPoints; ++i) {
|
||||
setSharpnessColor(g_coarseVertexSharpness[i], &r, &g, &b);
|
||||
vbo.push_back(g_positions[i*3+0]);
|
||||
vbo.push_back(g_positions[i*3+1]);
|
||||
vbo.push_back(g_positions[i*3+2]);
|
||||
vbo.push_back(r);
|
||||
vbo.push_back(g);
|
||||
vbo.push_back(b);
|
||||
}
|
||||
|
||||
glBindVertexArray(g_cageVertexVAO);
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, g_cageVertexVBO);
|
||||
glBufferData(GL_ARRAY_BUFFER, (int)vbo.size() * sizeof(float), &vbo[0],
|
||||
GL_STATIC_DRAW);
|
||||
|
||||
glEnableVertexAttribArray(g_defaultProgram.attrPosition);
|
||||
glEnableVertexAttribArray(g_defaultProgram.attrColor);
|
||||
glVertexAttribPointer(g_defaultProgram.attrPosition,
|
||||
3, GL_FLOAT, GL_FALSE, sizeof (GLfloat) * 6, 0);
|
||||
glVertexAttribPointer(g_defaultProgram.attrColor,
|
||||
3, GL_FLOAT, GL_FALSE, sizeof (GLfloat) * 6, (void*)12);
|
||||
|
||||
glPointSize(10.0f);
|
||||
glDrawArrays(GL_POINTS, 0, numPoints);
|
||||
glPointSize(1.0f);
|
||||
|
||||
glBindVertexArray(0);
|
||||
glUseProgram(0);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
union Effect {
|
||||
@ -902,7 +692,6 @@ public:
|
||||
|
||||
// compile shader program
|
||||
|
||||
|
||||
GLDrawConfig *config = new GLDrawConfig(GLUtils::GetShaderVersionInclude().c_str());
|
||||
|
||||
Far::PatchDescriptor::Type type = effectDesc.desc.GetType();
|
||||
@ -1339,11 +1128,12 @@ display() {
|
||||
if (g_displayStyle == kWire)
|
||||
glEnable(GL_CULL_FACE);
|
||||
|
||||
if (g_drawCageEdges)
|
||||
drawCageEdges();
|
||||
// draw the control mesh
|
||||
int stride = g_displayStyle == kInterleavedVaryingColor ? 7 : 3;
|
||||
g_controlMeshDisplay.Draw(vbo, stride*sizeof(float),
|
||||
g_transformData.ModelViewProjectionMatrix);
|
||||
|
||||
if (g_drawCageVertices)
|
||||
drawCageVertices();
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
|
||||
fb->ApplyImageShader();
|
||||
|
||||
@ -1390,19 +1180,18 @@ display() {
|
||||
g_hud.DrawString(10, y, "Draw calls : %d", numDrawCalls); y+= 20;
|
||||
g_hud.DrawString(10, y, "Primitives : %d", numPrimsGenerated); y+= 20;
|
||||
g_hud.DrawString(10, y, "Vertices : %d", g_mesh->GetNumVertices()); y+= 20;
|
||||
g_hud.DrawString(10, y, "Scheme : %s", g_scheme==kBilinear ? "BILINEAR" : (g_scheme == kLoop ? "LOOP" : "CATMARK")); y+= 20;
|
||||
g_hud.DrawString(10, y, "GPU Kernel : %.3f ms", g_gpuTime); y+= 20;
|
||||
g_hud.DrawString(10, y, "CPU Kernel : %.3f ms", g_cpuTime); y+= 20;
|
||||
g_hud.DrawString(10, y, "GPU Draw : %.3f ms", drawGpuTime); y+= 20;
|
||||
g_hud.DrawString(10, y, "CPU Draw : %.3f ms", drawCpuTime); y+= 20;
|
||||
g_hud.DrawString(10, y, "FPS : %3.1f", fps); y+= 20;
|
||||
g_hud.DrawString(10, y, "CPU Kernel : %.3f ms", g_cpuTime); y+= 20;
|
||||
g_hud.DrawString(10, y, "GPU Draw : %.3f ms", drawGpuTime); y+= 20;
|
||||
g_hud.DrawString(10, y, "CPU Draw : %.3f ms", drawCpuTime); y+= 20;
|
||||
g_hud.DrawString(10, y, "FPS : %3.1f", fps); y+= 20;
|
||||
|
||||
g_hud.Flush();
|
||||
}
|
||||
|
||||
glFinish();
|
||||
|
||||
//checkGLErrors("display leave");
|
||||
GLUtils::CheckGLErrors("display leave\n");
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
@ -1453,12 +1242,7 @@ static void
|
||||
uninitGL() {
|
||||
|
||||
glDeleteQueries(2, g_queries);
|
||||
|
||||
glDeleteBuffers(1, &g_cageVertexVBO);
|
||||
glDeleteBuffers(1, &g_cageEdgeVBO);
|
||||
glDeleteVertexArrays(1, &g_vao);
|
||||
glDeleteVertexArrays(1, &g_cageVertexVAO);
|
||||
glDeleteVertexArrays(1, &g_cageEdgeVAO);
|
||||
|
||||
if (g_mesh)
|
||||
delete g_mesh;
|
||||
@ -1514,11 +1298,6 @@ keyboard(GLFWwindow *, int key, int /* scancode */, int event, int /* mods */) {
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
static void
|
||||
rebuildOsdMesh() {
|
||||
createOsdMesh( g_defaultShapes[ g_currentShape ], g_level, g_kernel, g_defaultShapes[ g_currentShape ].scheme );
|
||||
}
|
||||
|
||||
static void
|
||||
callbackDisplayStyle(int b) {
|
||||
if (g_displayStyle == kVaryingColor or b == kVaryingColor or
|
||||
@ -1526,7 +1305,7 @@ callbackDisplayStyle(int b) {
|
||||
g_displayStyle == kFaceVaryingColor or b == kFaceVaryingColor) {
|
||||
// need to rebuild for varying reconstruct
|
||||
g_displayStyle = b;
|
||||
rebuildOsdMesh();
|
||||
rebuildMesh();
|
||||
return;
|
||||
}
|
||||
g_displayStyle = b;
|
||||
@ -1535,7 +1314,7 @@ callbackDisplayStyle(int b) {
|
||||
static void
|
||||
callbackEndCap(int endCap) {
|
||||
g_endCap = endCap;
|
||||
rebuildOsdMesh();
|
||||
rebuildMesh();
|
||||
}
|
||||
|
||||
static void
|
||||
@ -1559,13 +1338,13 @@ callbackKernel(int k) {
|
||||
}
|
||||
#endif
|
||||
|
||||
rebuildOsdMesh();
|
||||
rebuildMesh();
|
||||
}
|
||||
|
||||
static void
|
||||
callbackLevel(int l) {
|
||||
g_level = l;
|
||||
rebuildOsdMesh();
|
||||
rebuildMesh();
|
||||
}
|
||||
|
||||
static void
|
||||
@ -1577,7 +1356,7 @@ callbackModel(int m) {
|
||||
m = (int)g_defaultShapes.size() - 1;
|
||||
|
||||
g_currentShape = m;
|
||||
rebuildOsdMesh();
|
||||
rebuildMesh();
|
||||
}
|
||||
|
||||
static void
|
||||
@ -1587,11 +1366,11 @@ callbackCheckBox(bool checked, int button) {
|
||||
switch(button) {
|
||||
case kHUD_CB_ADAPTIVE:
|
||||
g_adaptive = checked;
|
||||
rebuildOsdMesh();
|
||||
rebuildMesh();
|
||||
return;
|
||||
case kHUD_CB_SINGLE_CREASE_PATCH:
|
||||
g_singleCreasePatch = checked;
|
||||
rebuildOsdMesh();
|
||||
rebuildMesh();
|
||||
return;
|
||||
default:
|
||||
break;
|
||||
@ -1599,11 +1378,11 @@ callbackCheckBox(bool checked, int button) {
|
||||
}
|
||||
|
||||
switch (button) {
|
||||
case kHUD_CB_DISPLAY_CAGE_EDGES:
|
||||
g_drawCageEdges = checked;
|
||||
case kHUD_CB_DISPLAY_CONTROL_MESH_EDGES:
|
||||
g_controlMeshDisplay.SetEdgesDisplay(checked);
|
||||
break;
|
||||
case kHUD_CB_DISPLAY_CAGE_VERTS:
|
||||
g_drawCageVertices = checked;
|
||||
case kHUD_CB_DISPLAY_CONTROL_MESH_VERTS:
|
||||
g_controlMeshDisplay.SetVerticesDisplay(checked);
|
||||
break;
|
||||
case kHUD_CB_ANIMATE_VERTICES:
|
||||
g_moveScale = checked;
|
||||
@ -1642,10 +1421,14 @@ initHUD() {
|
||||
|
||||
g_hud.SetFrameBuffer(new SSAOGLFrameBuffer);
|
||||
|
||||
g_hud.AddCheckBox("Cage Edges (H)", g_drawCageEdges != 0,
|
||||
10, 10, callbackCheckBox, kHUD_CB_DISPLAY_CAGE_EDGES, 'h');
|
||||
g_hud.AddCheckBox("Cage Verts (J)", g_drawCageVertices != 0,
|
||||
10, 30, callbackCheckBox, kHUD_CB_DISPLAY_CAGE_VERTS, 'j');
|
||||
g_hud.AddCheckBox("Control edges (H)",
|
||||
g_controlMeshDisplay.GetEdgesDisplay(),
|
||||
10, 10, callbackCheckBox,
|
||||
kHUD_CB_DISPLAY_CONTROL_MESH_EDGES, 'h');
|
||||
g_hud.AddCheckBox("Control vertices (J)",
|
||||
g_controlMeshDisplay.GetVerticesDisplay(),
|
||||
10, 30, callbackCheckBox,
|
||||
kHUD_CB_DISPLAY_CONTROL_MESH_VERTS, 'j');
|
||||
g_hud.AddCheckBox("Animate vertices (M)", g_moveScale != 0,
|
||||
10, 50, callbackCheckBox, kHUD_CB_ANIMATE_VERTICES, 'm');
|
||||
g_hud.AddCheckBox("Patch Color (P)", g_displayPatchColor != 0,
|
||||
@ -1741,10 +1524,6 @@ initGL() {
|
||||
glGenQueries(2, g_queries);
|
||||
|
||||
glGenVertexArrays(1, &g_vao);
|
||||
glGenVertexArrays(1, &g_cageVertexVAO);
|
||||
glGenVertexArrays(1, &g_cageEdgeVAO);
|
||||
glGenBuffers(1, &g_cageVertexVBO);
|
||||
glGenBuffers(1, &g_cageEdgeVBO);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
@ -1892,12 +1671,11 @@ int main(int argc, char ** argv) {
|
||||
g_adaptive = GLUtils::SupportsAdaptiveTessellation();
|
||||
|
||||
initGL();
|
||||
linkDefaultProgram();
|
||||
|
||||
glfwSwapInterval(0);
|
||||
|
||||
initHUD();
|
||||
rebuildOsdMesh();
|
||||
rebuildMesh();
|
||||
|
||||
while (g_running) {
|
||||
idle();
|
||||
|
Loading…
Reference in New Issue
Block a user