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:
Takahito Tejima 2015-05-31 15:08:37 -07:00
parent 39e22e55b2
commit 7394bf5f51
13 changed files with 1005 additions and 1046 deletions

View File

@ -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

View 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);
}

View 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

View 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;
}

View 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

View File

@ -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;
}

View File

@ -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));
}
//------------------------------------------------------------------------------

View File

@ -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();

View File

@ -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();

View File

@ -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();

View File

@ -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,

View File

@ -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);
}

View File

@ -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();