OpenSubdiv/examples/glBatchViewer/delegate.cpp

174 lines
5.9 KiB
C++
Raw Normal View History

2013-05-10 02:18:32 +00:00
//
2013-07-18 21:19:50 +00:00
// Copyright 2013 Pixar
2013-05-10 02:18:32 +00:00
//
2013-07-18 21:19:50 +00:00
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License
// and the following modification to it: Section 6 Trademarks.
// deleted and replaced with:
2013-05-10 02:18:32 +00:00
//
2013-07-18 21:19:50 +00:00
// 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 for reproducing
// the content of the NOTICE file.
2013-05-10 02:18:32 +00:00
//
2013-07-18 21:19:50 +00:00
// You may obtain a copy of the License at
2013-05-10 02:18:32 +00:00
//
2013-07-18 21:19:50 +00:00
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
// either express or implied. See the License for the specific
// language governing permissions and limitations under the
// License.
2013-05-10 02:18:32 +00:00
//
#include "delegate.h"
#include <osd/opengl.h>
2013-05-10 02:18:32 +00:00
MyDrawContext::MyDrawContext() {
glGenVertexArrays(1, &_vao);
2013-05-10 02:18:32 +00:00
}
MyDrawContext::~MyDrawContext() {
glDeleteVertexArrays(1, &_vao);
2013-05-10 02:18:32 +00:00
}
MyDrawContext*
MyDrawContext::Create(OpenSubdiv::FarPatchTables const *patchTables, bool requireFVarData)
{
MyDrawContext * result = new MyDrawContext();
if (patchTables) {
if (result->create(patchTables, requireFVarData)) {
return result;
} else {
delete result;
}
}
return NULL;
}
2013-05-10 02:18:32 +00:00
// ----------------------------------------------------------------------------
void
MyDrawDelegate::Bind(OpenSubdiv::OsdUtilMeshBatchBase<MyDrawContext> *batch, EffectHandle const &effect) {
if (batch != _currentBatch) {
// bind batch
_currentBatch = batch;
MyDrawContext *drawContext = batch->GetDrawContext();
// bind vao
glBindVertexArray(drawContext->GetVertexArray());
// bind vbo state
glBindBuffer(GL_ARRAY_BUFFER, batch->BindVertexBuffer());
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, drawContext->GetPatchIndexBuffer());
// vertex attrib
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof (GLfloat) * 3, 0);
if (effect->displayStyle == kVaryingColor) {
glBindBuffer(GL_ARRAY_BUFFER, batch->BindVaryingBuffer());
glEnableVertexAttribArray(1);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof (GLfloat) * 3, 0);
}
// bind other builtin texture buffers
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_BUFFER, drawContext->GetVertexTextureBuffer());
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_BUFFER, drawContext->GetVertexValenceTextureBuffer());
glActiveTexture(GL_TEXTURE2);
glBindTexture(GL_TEXTURE_BUFFER, drawContext->GetQuadOffsetsTextureBuffer());
glActiveTexture(GL_TEXTURE3);
glBindTexture(GL_TEXTURE_BUFFER, drawContext->GetPatchParamTextureBuffer());
if (drawContext->GetFvarDataTextureBuffer()) {
glActiveTexture(GL_TEXTURE4);
glBindTexture(GL_TEXTURE_BUFFER, drawContext->GetFvarDataTextureBuffer());
}
}
if (effect != _currentEffect) {
_currentEffect = effect;
// bind effect
}
2013-05-10 02:18:32 +00:00
}
void
MyDrawDelegate::Unbind(OpenSubdiv::OsdUtilMeshBatchBase<MyDrawContext> *batch, EffectHandle const &effect) {
2013-05-10 02:18:32 +00:00
}
void
MyDrawDelegate::Begin() {
_currentBatch = NULL;
_currentEffect = NULL;
2013-05-10 02:18:32 +00:00
}
void
MyDrawDelegate::End() {
_currentBatch = NULL;
_currentEffect = NULL;
glBindVertexArray(0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
glDisableVertexAttribArray(0);
glDisableVertexAttribArray(1);
2013-05-10 02:18:32 +00:00
}
void
MyDrawDelegate::DrawElements(OpenSubdiv::OsdDrawContext::PatchArray const &patchArray) {
2013-05-10 02:18:32 +00:00
// bind patchType-wise effect state
// can be skipped (if config is not changed)
MyDrawConfig *config = GetDrawConfig(_currentEffect, patchArray.GetDescriptor());
2013-05-10 02:18:32 +00:00
GLuint program = config->program;
if (true /* if config is different from previous call */) {
glUseProgram(program);
2013-05-17 22:53:36 +00:00
#if defined(GL_ARB_tessellation_shader) || defined(GL_VERSION_4_0)
2013-05-10 02:18:32 +00:00
glPatchParameteri(GL_PATCH_VERTICES, patchArray.GetDescriptor().GetNumControlVertices());
2013-05-17 22:53:36 +00:00
#endif
2013-05-10 02:18:32 +00:00
// bind patchArray state and draw
}
// apply patch color
_currentEffect->BindDrawConfig(config, patchArray.GetDescriptor());
2013-05-10 02:18:32 +00:00
glUniform1i(config->primitiveIdBaseUniform, patchArray.GetPatchIndex());
2013-05-10 02:18:32 +00:00
if (patchArray.GetDescriptor().GetType() == OpenSubdiv::FarPatchTables::GREGORY ||
patchArray.GetDescriptor().GetType() == OpenSubdiv::FarPatchTables::GREGORY_BOUNDARY){
glUniform1i(config->gregoryQuadOffsetBaseUniform, patchArray.GetQuadOffsetIndex());
}
if (patchArray.GetDescriptor().GetType() == OpenSubdiv::FarPatchTables::QUADS) {
glDrawElements(GL_LINES_ADJACENCY, patchArray.GetNumIndices(), GL_UNSIGNED_INT,
(void*)(patchArray.GetVertIndex()*sizeof(GLuint)));
} else if (patchArray.GetDescriptor().GetType() == OpenSubdiv::FarPatchTables::TRIANGLES) {
glDrawElements(GL_TRIANGLES, patchArray.GetNumIndices(), GL_UNSIGNED_INT,
(void*)(patchArray.GetVertIndex()*sizeof(GLuint)));
2013-05-10 02:18:32 +00:00
} else {
2013-05-17 22:53:36 +00:00
#if defined(GL_ARB_tessellation_shader) || defined(GL_VERSION_4_0)
2013-05-10 02:18:32 +00:00
glDrawElements(GL_PATCHES, patchArray.GetNumIndices(), GL_UNSIGNED_INT,
(void*)(patchArray.GetVertIndex()*sizeof(GLuint)));
2013-05-17 22:53:36 +00:00
#endif
2013-05-10 02:18:32 +00:00
}
_numDrawCalls++;
}
bool
MyDrawDelegate::IsCombinable(EffectHandle const &a, EffectHandle const &b) const {
return a == b;
}
2013-05-10 02:18:32 +00:00
MyDrawConfig *
MyDrawDelegate::GetDrawConfig(EffectHandle &effect, OpenSubdiv::OsdDrawContext::PatchDescriptor desc) {
2013-05-10 02:18:32 +00:00
return _effectRegistry.GetDrawConfig(effect->GetEffectDescriptor(), desc);
2013-05-10 02:18:32 +00:00
}