Merge branch 'release/v1_2_3'

This commit is contained in:
manuelk 2013-06-17 19:36:01 -07:00
commit 9f5c2df769
88 changed files with 2144 additions and 3734 deletions

View File

@ -59,7 +59,6 @@ if( OPENGL_FOUND AND (GLEW_FOUND AND GLFW_FOUND) OR (APPLE AND GLFW_FOUND))
add_subdirectory(glViewer)
add_subdirectory(glBatchViewer)
add_subdirectory(simpleCpu)
# add_subdirectory(evalTest)
add_subdirectory(limitEval)
if(OPENGL_4_3_FOUND)
# the paintTest example requires GL functionality not available on OSX

View File

@ -268,9 +268,9 @@ apply(float *v, const float *m)
{
float r[4];
r[0] = v[0] * m[0] + v[1] * m[4] + v[2] * m[8] + v[3] * m[12];
r[1] = v[1] * m[1] + v[1] * m[5] + v[2] * m[9] + v[3] * m[13];
r[2] = v[2] * m[2] + v[1] * m[6] + v[2] * m[10] + v[3] * m[14];
r[3] = v[3] * m[3] + v[1] * m[7] + v[2] * m[11] + v[3] * m[14];
r[1] = v[0] * m[1] + v[1] * m[5] + v[2] * m[9] + v[3] * m[13];
r[2] = v[0] * m[2] + v[1] * m[6] + v[2] * m[10] + v[3] * m[14];
r[3] = v[0] * m[3] + v[1] * m[7] + v[2] * m[11] + v[3] * m[15];
v[0] = r[0];
v[1] = r[1];
v[2] = r[2];

View File

@ -1,119 +0,0 @@
#
# Copyright (C) Pixar. All rights reserved.
#
# This license governs use of the accompanying software. If you
# use the software, you accept this license. If you do not accept
# the license, do not use the software.
#
# 1. Definitions
# The terms "reproduce," "reproduction," "derivative works," and
# "distribution" have the same meaning here as under U.S.
# copyright law. A "contribution" is the original software, or
# any additions or changes to the software.
# A "contributor" is any person or entity that distributes its
# contribution under this license.
# "Licensed patents" are a contributor's patent claims that read
# directly on its contribution.
#
# 2. Grant of Rights
# (A) Copyright Grant- Subject to the terms of this license,
# including the license conditions and limitations in section 3,
# each contributor grants you a non-exclusive, worldwide,
# royalty-free copyright license to reproduce its contribution,
# prepare derivative works of its contribution, and distribute
# its contribution or any derivative works that you create.
# (B) Patent Grant- Subject to the terms of this license,
# including the license conditions and limitations in section 3,
# each contributor grants you a non-exclusive, worldwide,
# royalty-free license under its licensed patents to make, have
# made, use, sell, offer for sale, import, and/or otherwise
# dispose of its contribution in the software or derivative works
# of the contribution in the software.
#
# 3. Conditions and Limitations
# (A) No Trademark License- This license does not grant you
# rights to use any contributor's name, logo, or trademarks.
# (B) If you bring a patent claim against any contributor over
# patents that you claim are infringed by the software, your
# patent license from such contributor to the software ends
# automatically.
# (C) If you distribute any portion of the software, you must
# retain all copyright, patent, trademark, and attribution
# notices that are present in the software.
# (D) If you distribute any portion of the software in source
# code form, you may do so only under this license by including a
# complete copy of this license with your distribution. If you
# distribute any portion of the software in compiled or object
# code form, you may only do so under a license that complies
# with this license.
# (E) The software is licensed "as-is." You bear the risk of
# using it. The contributors give no express warranties,
# guarantees or conditions. You may have additional consumer
# rights under your local laws which this license cannot change.
# To the extent permitted under your local laws, the contributors
# exclude the implied warranties of merchantability, fitness for
# a particular purpose and non-infringement.
#
# *** evalTest ***
set(SHADER_FILES
shader.glsl
)
set(PLATFORM_LIBRARIES
${OSD_LINK_TARGET}
${OPENGL_LIBRARY}
${GLEW_LIBRARY}
${GLFW_LIBRARIES}
)
include_directories(
${PROJECT_SOURCE_DIR}/opensubdiv
${PROJECT_SOURCE_DIR}/regression
${GLEW_INCLUDE_DIR}
${GLFW_INCLUDE_DIR}
)
#-------------------------------------------------------------------------------
# Shader Stringification
# We want to use preprocessor include directives to include GLSL and OpenCL
# shader source files in cpp files, but since the sources contain newline
# characters we would need raw string literals from C++11 to do this directly.
# To avoid depending on C++11 we instead use a small tool called "line_quote"
# to generate source files that are suitable for direct inclusion.
foreach(shader_file ${SHADER_FILES})
string(REGEX REPLACE ".*[.](.*)" "\\1" extension ${shader_file})
string(REGEX REPLACE "(.*)[.].*" "\\1.inc" inc_file ${shader_file})
list(APPEND INC_FILES ${inc_file})
add_custom_command(
OUTPUT ${CMAKE_CURRENT_SOURCE_DIR}/${inc_file}
COMMAND stringify ${CMAKE_CURRENT_SOURCE_DIR}/${shader_file}
${CMAKE_CURRENT_SOURCE_DIR}/${inc_file}
DEPENDS stringify ${CMAKE_CURRENT_SOURCE_DIR}/${shader_file}
)
endforeach()
if(APPLE)
_add_glfw_executable(evalTest
mainApple.mm
evalTest.cpp
${SHADER_FILES}
${INC_FILES}
)
else()
_add_glfw_executable(evalTest
evalTest.cpp
mainGlut.cpp
${SHADER_FILES}
${INC_FILES}
)
endif()
target_link_libraries(evalTest
${PLATFORM_LIBRARIES}
)

View File

@ -1,210 +0,0 @@
#pragma once
#include <limits>
#include <cmath>
#include <vector>
#include <stdlib.h>
#include <stdio.h>
#include <iostream>
#include <iomanip>
//
// A few basic linear algebra operations
//
//
// Make the given matrix an identity matrix
//
inline void setIdentity(float* m)
{
m[0] = m[5] = m[10] = m[15] = 1.0f;
m[1] = m[2] = m[3] = m[4] = m[6] = m[7] = m[8] = m[9] = m[11] = m[12] = m[13] = m[14] = 0.0f;
}
//
// Multiply A * B and store the result in D
//
inline void
multMatrix(float *d, const float *a, const float *b)
{
for (int i=0; i<4; ++i)
{
for (int j=0; j<4; ++j)
{
d[i*4 + j] =
a[i*4 + 0] * b[0*4 + j] +
a[i*4 + 1] * b[1*4 + j] +
a[i*4 + 2] * b[2*4 + j] +
a[i*4 + 3] * b[3*4 + j];
}
}
}
//
// Create a perspective projection matrix
//
void setPersp( float fov, float aspect, float znear, float zfar, float* m )
{
float xymax = znear * tanf(fov * 3.141592653589793238462f / 360.f);
float ymin = -xymax;
float xmin = -xymax;
float width = xymax - xmin;
float height = xymax - ymin;
float depth = zfar - znear;
float q = -(zfar + znear) / depth;
float qn = -2 * (zfar * znear) / depth;
float w = 2 * znear / width;
w = w / aspect;
float h = 2 * znear / height;
m[0] = w;
m[1] = 0.f;
m[2] = 0.f;
m[3] = 0.f;
m[4] = 0.f;
m[5] = h;
m[6] = 0.f;
m[7] = 0.f;
m[8] = 0.f;
m[9] = 0.f;
m[10] = q;
m[11] = -1;
m[12] = 0.f;
m[13] = 0.f;
m[14] = qn;
m[15] = 0.f;
}
//
// Apply a translation to the given matrix m
//
void
translateMatrix(float x, float y, float z, float* m)
{
m[0] += m[3]*x; m[4] += m[7]*x; m[8] += m[11]*x; m[12] += m[15]*x;
m[1] += m[3]*y; m[5] += m[7]*y; m[9] += m[11]*y; m[13] += m[15]*y;
m[2] += m[3]*z; m[6] += m[7]*z; m[10]+= m[11]*z; m[14] += m[15]*z;
}
//
// Apply a rotation to the given matrix m
//
void
rotateMatrix(float angle, float x, float y, float z, float* m)
{
float rads = float((2*3.14159 / 360.) * angle);
float c = cosf(rads);
float s = sinf(rads);
float xx = x * x;
float xy = x * y;
float xz = x * z;
float yy = y * y;
float yz = y * z;
float zz = z * z;
float m2[16];
m2[0] = xx * (1 - c) + c;
m2[4] = xy * (1 - c) - z * s;
m2[8] = xz * (1 - c) + y * s;
m2[12] = 0;
m2[1] = xy * (1 - c) + z * s;
m2[5] = yy * (1 - c) + c;
m2[9] = yz * (1 - c) - x * s;
m2[13] = 0;
m2[2] = xz * (1 - c) - y * s;
m2[6] = yz * (1 - c) + x * s;
m2[10]= zz * (1 - c) + c;
m2[14]= 0;
m2[3]= 0;
m2[7]= 0;
m2[11]= 0;
m2[15]= 1;
float mOrig[16];
for (int i = 0; i < 16; i++)
mOrig[i] = m[i];
multMatrix(m, mOrig, m2);
}
//
// Print out the matrix (as usual, column-major order is assumed)
//
inline void printMatrix(float* m)
{
for (int r = 0; r < 4; r++) {
std::cout << " ";
for (int c = 0; c < 4; c++) {
std::cout << std::setprecision(3) << m[c*4 + r];
if (c != 3)
std::cout << ",";
else
std::cout << std::endl;
}
}
}
//
// Perform a cross-product of three points to calculate a face normal
//
inline void
cross(float *n, const float *p0, const float *p1, const float *p2)
{
float a[3] = { p1[0]-p0[0], p1[1]-p0[1], p1[2]-p0[2] };
float b[3] = { p2[0]-p0[0], p2[1]-p0[1], p2[2]-p0[2] };
n[0] = a[1]*b[2]-a[2]*b[1];
n[1] = a[2]*b[0]-a[0]*b[2];
n[2] = a[0]*b[1]-a[1]*b[0];
float rn = 1.0f/sqrtf(n[0]*n[0] + n[1]*n[1] + n[2]*n[2]);
n[0] *= rn;
n[1] *= rn;
n[2] *= rn;
}
//
// Normalize the given vector
//
inline void
normalize(float * p)
{
float dist = sqrtf( p[0]*p[0] + p[1]*p[1] + p[2]*p[2] );
p[0]/=dist;
p[1]/=dist;
p[2]/=dist;
}
//
// Compute the center of the list of points and the size of the bound
//
inline void
computeCenterAndSize(const std::vector<float>& positions, float* center, float* size)
{
float fmax = std::numeric_limits<float>().max(),
fmin = std::numeric_limits<float>().min();
float min[3] = { fmax, fmax, fmax};
float max[3] = { fmin, fmin, fmin};
for (size_t i=0; i < positions.size()/3; ++i) {
for(int j=0; j<3; ++j) {
float v = positions[i*3+j];
min[j] = std::min(min[j], v);
max[j] = std::max(max[j], v);
}
}
for (int j=0; j<3; ++j) {
center[j] = (min[j] + max[j]) * 0.5f;
*size += (max[j]-min[j])*(max[j]-min[j]);
}
*size = sqrtf(*size);
}

File diff suppressed because it is too large Load Diff

View File

@ -1,242 +0,0 @@
//
// This file contains standard OpenGL API calls that are mostly uninteresting if
// you are purely trying to learn OSD. The following operations are implemented
// here:
//
// * First time OpenGL state initialization
// * Compile vertex and fragment shaders
// * Link shaders into a program
// * Per-frame drawing state setup
//
#pragma once
//
// ### OS Compatibility
// The following is to ensure the example runs on Linux, Windows and OS X
//
#if defined(__APPLE__)
#include <OpenGL/gl3.h>
#define GLFW_INCLUDE_GL3
#define GLFW_NO_GLU
#else
#include <stdlib.h>
#include <GL/glew.h>
#if defined(WIN32)
#include <GL/wglew.h>
#endif
#endif
#if defined(GLFW_VERSION_3)
#include <GL/glfw3.h>
GLFWwindow* g_window=0;
GLFWmonitor* g_primary=0;
#else
#include <GL/glfw.h>
#endif
#include "algebra.h"
#include <iostream>
#include <fstream>
#include <sstream>
//
// Microsoft uses a slightly different snprintf declaration, which we hide
// here by aliasing it as snprintf
//
#if _MSC_VER
#define snprintf _snprintf
#endif
#if defined(__APPLE__)
#define drawString(x, y, ...);
/* \
GLUT on OSX means gl 2.1, so forgoe the text drawing until we have a better solution
{ char line[1024]; \
snprintf(line, 1024, __VA_ARGS__); \
char *p = line; \
glWindowPos2f(x, y); \
while(*p) { glutBitmapCharacter(GLUT_BITMAP_HELVETICA_12, *p++); } }
*/
#else
#define drawString(x, y, ...) \
{ char line[1024]; \
snprintf(line, 1024, __VA_ARGS__); \
char *p = line; \
glWindowPos2i(x, y); \
while(*p) { glutBitmapCharacter(GLUT_BITMAP_HELVETICA_12, *p++); } }
#endif
//
// These are standard OpenGL shader program handles. One for wire frame and one
// for shaded rendering
//
GLuint g_quadLineProgram = 0;
GLuint g_quadFillProgram = 0;
//
// To avoid reading the shader source from a file, we include it here as a string
// see [shader.glsl](shader.html).
//
static const char *shaderSource =
#include "shader.inc"
;
GLfloat g_modelView[16], g_proj[16], g_mvp[16];
void
bindProgram(GLuint program)
{
glUseProgram(program);
// shader uniform setting
GLint position = glGetUniformLocation(program, "lightSource[0].position");
GLint ambient = glGetUniformLocation(program, "lightSource[0].ambient");
GLint diffuse = glGetUniformLocation(program, "lightSource[0].diffuse");
GLint specular = glGetUniformLocation(program, "lightSource[0].specular");
GLint position1 = glGetUniformLocation(program, "lightSource[1].position");
GLint ambient1 = glGetUniformLocation(program, "lightSource[1].ambient");
GLint diffuse1 = glGetUniformLocation(program, "lightSource[1].diffuse");
GLint specular1 = glGetUniformLocation(program, "lightSource[1].specular");
glUniform4f(position, 0.5, 0.2f, 1.0f, 0.0f);
glUniform4f(ambient, 0.1f, 0.1f, 0.1f, 1.0f);
glUniform4f(diffuse, 0.7f, 0.7f, 0.7f, 1.0f);
glUniform4f(specular, 0.8f, 0.8f, 0.8f, 1.0f);
glUniform4f(position1, -0.8f, 0.4f, -1.0f, 0.0f);
glUniform4f(ambient1, 0.0f, 0.0f, 0.0f, 1.0f);
glUniform4f(diffuse1, 0.5f, 0.5f, 0.5f, 1.0f);
glUniform4f(specular1, 0.8f, 0.8f, 0.8f, 1.0f);
GLint otcMatrix = glGetUniformLocation(program, "objectToClipMatrix");
GLint oteMatrix = glGetUniformLocation(program, "objectToEyeMatrix");
multMatrix(g_mvp, g_modelView, g_proj);
glUniformMatrix4fv(otcMatrix, 1, false, g_mvp);
glUniformMatrix4fv(oteMatrix, 1, false, g_modelView);
}
static GLuint
compileShader(GLenum shaderType, const char *section, const char *define)
{
const char *sources[4];
char sdefine[64];
sprintf(sdefine, "#define %s\n", section);
sources[0] = "#version 330\n";
sources[1] = define;
sources[2] = sdefine;
sources[3] = shaderSource;
GLuint shader = glCreateShader(shaderType);
glShaderSource(shader, 4, sources, NULL);
glCompileShader(shader);
GLint status;
glGetShaderiv(shader, GL_COMPILE_STATUS, &status);
if( status == GL_FALSE ) {
GLchar emsg[1024];
glGetShaderInfoLog(shader, sizeof(emsg), 0, emsg);
fprintf(stderr, "Error compiling GLSL shader (%s): %s\n", section, emsg );
fprintf(stderr, "Section: %s\n", sdefine);
fprintf(stderr, "Defines: %s\n", define);
fprintf(stderr, "Source: %s\n", sources[2]);
exit(0);
}
return shader;
}
GLuint
linkProgram(const char *define)
{
GLuint vertexShader = compileShader(GL_VERTEX_SHADER, "VERTEX_SHADER", define);
GLuint fragmentShader = compileShader(GL_FRAGMENT_SHADER, "FRAGMENT_SHADER", define);
GLuint program = glCreateProgram();
glAttachShader(program, vertexShader);
glAttachShader(program, fragmentShader);
glBindAttribLocation(program, 0, "position");
glLinkProgram(program);
glDeleteShader(vertexShader);
glDeleteShader(fragmentShader);
GLint status;
glGetProgramiv(program, GL_LINK_STATUS, &status );
if( status == GL_FALSE ) {
GLchar emsg[1024];
glGetProgramInfoLog(program, sizeof(emsg), 0, emsg);
fprintf(stderr, "Error linking GLSL program : %s\n", emsg );
fprintf(stderr, "Defines: %s\n", define);
exit(0);
}
return program;
}
void
initGL()
{
glClearColor(0.1f, 0.1f, 0.1f, 1.0f);
glEnable(GL_DEPTH_TEST);
glEnable(GL_CULL_FACE);
glDepthFunc(GL_LEQUAL);
g_quadFillProgram = linkProgram("#define PRIM_QUAD\n#define GEOMETRY_OUT_FILL\n");
g_quadLineProgram = linkProgram("#define PRIM_QUAD\n#define GEOMETRY_OUT_LINE\n");
}
void
setupForDisplay(int width, int height, float size, float* center)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glViewport(0, 0, width, height);
setIdentity(g_proj);
setIdentity(g_modelView);
setIdentity(g_mvp);
// setup the projection
float aspect = width/(float)height;
setPersp(45.0f, aspect, 0.01f, 500.0f, g_proj);
// setup the model view matrix
translateMatrix(-center[0], -center[1], -center[2], g_modelView);
rotateMatrix(-90, 1, 0, 0, g_modelView); // z-up model
translateMatrix(0, 0, -size, g_modelView);
}
static void
checkGLErrors(std::string const & where = "")
{
GLuint err;
while ((err = glGetError()) != GL_NO_ERROR) {
std::cout << "Where = " << where << std::endl;
if (err == GL_INVALID_ENUM) {
std::cout << "GL_INVALID_ENUM\n";
} else
if (err == GL_INVALID_VALUE) {
std::cout << "GL_INVALID_VALUE\n";
} else
if (err == GL_INVALID_OPERATION) {
std::cout << "GL_INVALID_OPERATION\n";
} else
if (err == GL_INVALID_OPERATION) {
std::cout << "GL_INVALID_OPERATION\n";
} else
if (err == GL_OUT_OF_MEMORY) {
std::cout << "GL_OUT_OF_MEMORY\n";
} else {
std::cout << "Some other gl error \n";
}
}
}

View File

@ -1,176 +0,0 @@
#import <Cocoa/Cocoa.h>
#import <OpenGL/OpenGL.h>
#import <OpenGL/glu.h>
#import <wchar.h>
#import <iostream>
//
// Hooks back into the example code
//
extern void initOsd();
extern void updateGeom();
extern void display();
//
// Shared global state from the example
//
extern int g_width, g_height, g_frame;
//
// OSX application bootstrap
//
@class View;
@interface View : NSOpenGLView <NSWindowDelegate> {
NSRect m_frameRect;
BOOL m_didInit;
uint64_t m_previousTime;
NSTimer* m_timer;
}
- (void) animate;
@end
@implementation View
-(void)windowWillClose:(NSNotification *)note
{
[[NSApplication sharedApplication] terminate:self];
}
- (void) timerFired:(NSTimer*) timer
{
[self animate];
}
- (id) initWithFrame: (NSRect) frame
{
m_didInit = FALSE;
//
// Various GL state, of note is the 3.2 Core profile selection
// and 8x antialiasing, which we might want to disable for performance
//
int attribs[] = {
NSOpenGLPFAAccelerated,
NSOpenGLPFADoubleBuffer,
NSOpenGLPFADepthSize, 24,
NSOpenGLPFAAlphaSize, 8,
NSOpenGLPFAColorSize, 32,
NSOpenGLPFAOpenGLProfile, NSOpenGLProfileVersion3_2Core,
NSOpenGLPFANoRecovery,
kCGLPFASampleBuffers, 1,
kCGLPFASamples, 8,
0
};
NSOpenGLPixelFormat *fmt = [[NSOpenGLPixelFormat alloc]
initWithAttributes:(NSOpenGLPixelFormatAttribute*) attribs];
self = [self initWithFrame:frame pixelFormat:fmt];
[fmt release];
m_frameRect = frame;
m_timer = [[NSTimer
scheduledTimerWithTimeInterval:1.0f/120.0f
target:self
selector:@selector(timerFired:)
userInfo:nil
repeats:YES] retain];
return self;
}
- (void) drawRect:(NSRect) theRect
{
if (!m_didInit) {
initOsd();
m_didInit = YES;
[[self window] setLevel: NSFloatingWindowLevel];
[[self window] makeKeyAndOrderFront: self];
[[self window] setTitle: [NSString stringWithUTF8String: "SimpleCPU"]];
}
// run the example code
display();
// make sure GL state is clean
assert(glGetError() == GL_NO_ERROR);
[[self openGLContext] flushBuffer];
}
- (void) animate
{
g_frame++;
updateGeom();
[self display];
}
@end
int main(int argc, const char *argv[])
{
//
// It seems that some ATI cards fall back to software when rendering geometry shaders
// but only *sometimes*. Post this notice so it's obvious that OSD isn't the problem.
//
// XXX(jcowles): we should only use vertex and fragment shaders to avoid this potential confusion
//
std::cout << "--------------------------------------------------------------------------------" << std::endl;
std::cout << "NOTICE: Some Apple hardware runs geometry shaders in software, which will cause" << std::endl;
std::cout << " this demo to run extremely slowly. That slowness is not related to OSD" << std::endl;
std::cout << " and can be avoided by not using OpenGL geometry shaders." << std::endl;
std::cout << "--------------------------------------------------------------------------------" << std::endl;
NSAutoreleasePool *pool = [NSAutoreleasePool new];
NSApplication *NSApp = [NSApplication sharedApplication];
[NSApp setActivationPolicy:NSApplicationActivationPolicyRegular];
id menubar = [[NSMenu new] autorelease];
id appMenuItem = [[NSMenuItem new] autorelease];
[menubar addItem:appMenuItem];
[NSApp setMainMenu:menubar];
id appMenu = [[NSMenu new] autorelease];
id appName = [[NSProcessInfo processInfo] processName];
id quitTitle = [@"Quit " stringByAppendingString:appName];
id quitMenuItem = [[[NSMenuItem alloc] initWithTitle:quitTitle
action:@selector(terminate:) keyEquivalent:@"q"] autorelease];
[appMenu addItem:quitMenuItem];
[appMenuItem setSubmenu:appMenu];
NSRect screenBounds = [[NSScreen mainScreen] frame];
g_width = 512;
g_height = 512;
NSRect viewBounds = NSMakeRect(0, 0, g_width, g_height);
View* view = [[View alloc] initWithFrame:viewBounds];
NSRect centered = NSMakeRect(NSMidX(screenBounds) - NSMidX(viewBounds),
NSMidY(screenBounds) - NSMidY(viewBounds),
viewBounds.size.width, viewBounds.size.height);
NSWindow *window = [[NSWindow alloc]
initWithContentRect:centered
styleMask:NSTitledWindowMask | NSClosableWindowMask | NSMiniaturizableWindowMask
backing:NSBackingStoreBuffered
defer:NO];
[window setContentView:view];
[window setDelegate:view];
[window makeKeyAndOrderFront:nil];
[NSApp activateIgnoringOtherApps:YES];
[view release];
[NSApp run];
[pool release];
return EXIT_SUCCESS;
}

View File

@ -1,74 +0,0 @@
#include <stdlib.h>
#include <GL/glew.h>
#include <GL/glut.h>
extern void initOsd();
extern void updateGeom();
extern void display();
extern int g_width, g_height, g_frame;
//
// ### Misc. GLUT Callback Methods
// Reshape is called when the window is resized, here we need the width and
// height so that we can correctly adjust the aspect ratio of the projection
// matrix.
//
void
reshape(int width, int height)
{
g_width = width;
g_height = height;
}
//
// Idle is called between frames, here we advance the frame number and update
// the procedural animation that is being applied to the mesh
//
void
idle()
{
g_frame++;
updateGeom();
glutPostRedisplay();
}
//
// ### Draw the Mesh
// Display handles all drawing per frame. We first call the setupForDisplay
// helper method to setup some uninteresting GL state and then bind the mesh
// using the buffers provided by our OSD objects
//
void
glutDisplay()
{
display();
glutSwapBuffers();
}
int main(int argc, char ** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGBA |GLUT_DOUBLE | GLUT_DEPTH);
glutInitWindowSize(1024, 1024);
glutCreateWindow("CPU Subdivision Example");
//
// Setup glut, glew and some initial GL state
//
glutDisplayFunc(glutDisplay);
glutReshapeFunc(reshape);
glewInit();
initOsd();
//
// Start the main glut drawing loop
//
glutIdleFunc(idle);
glutMainLoop();
}

View File

@ -1,38 +0,0 @@
Setup:
======
* clone docco
git clone https://github.com/jashkenas/docco.git
* install node.js
http://nodejs.org/
* npm install commander
* sudo easy_install Pygments
Generate documentation:
=======================
$ ~/src/docco/bin/docco simpleCpuSubdivision.cpp
Trina's Setup
(setup above didn't work for me, here's what I did, YMMV)
To Generate docco html file:
* sudo easy_install Pygments
* install node from http://nodejs.org/
* put source into /usr/local/src
% cd /usr/local/src/node-VERSION
% ./configure
% make
% make install
% npm install -g docco
* docco should now be in /usr/local/bin
* rehash
* cd /your/source/code/directory
* docco yoursource.cpp
voila!
* docs go into /your/source/code/directory/docs

View File

@ -65,12 +65,12 @@ layout (location=1) in vec3 normal;
out block {
OutputVertex v;
} output;
} outpt;
void main()
{
output.v.position = ModelViewMatrix * position;
output.v.normal = (ModelViewMatrix * vec4(normal, 0.0)).xyz;
outpt.v.position = ModelViewMatrix * position;
outpt.v.normal = (ModelViewMatrix * vec4(normal, 0.0)).xyz;
}
#endif
@ -90,7 +90,7 @@ void main()
in block {
OutputVertex v;
} input[4];
} inpt[4];
#endif // PRIM_QUAD
@ -104,7 +104,7 @@ void main()
in block {
OutputVertex v;
} input[3];
} inpt[3];
#endif // PRIM_TRI
@ -115,23 +115,24 @@ void main()
in block {
OutputVertex v;
} input[1];
} inpt[1];
#endif // PRIM_POINT
out block {
OutputVertex v;
} output;
noperspective out vec4 edgeDistance;
} outpt;
void emit(int index, vec3 normal)
{
output.v.position = input[index].v.position;
outpt.v.position = inpt[index].v.position;
#ifdef SMOOTH_NORMALS
output.v.normal = input[index].v.normal;
outpt.v.normal = inpt[index].v.normal;
#else
output.v.normal = normal;
outpt.v.normal = normal;
#endif
gl_Position = ProjectionMatrix * input[index].v.position;
gl_Position = ProjectionMatrix * inpt[index].v.position;
EmitVertex();
}
@ -147,18 +148,18 @@ float edgeDistance(vec4 p, vec4 p0, vec4 p1)
void emit(int index, vec3 normal, vec4 edgeVerts[EDGE_VERTS])
{
output.v.edgeDistance[0] =
outpt.edgeDistance[0] =
edgeDistance(edgeVerts[index], edgeVerts[0], edgeVerts[1]);
output.v.edgeDistance[1] =
outpt.edgeDistance[1] =
edgeDistance(edgeVerts[index], edgeVerts[1], edgeVerts[2]);
#ifdef PRIM_TRI
output.v.edgeDistance[2] =
outpt.edgeDistance[2] =
edgeDistance(edgeVerts[index], edgeVerts[2], edgeVerts[0]);
#endif
#ifdef PRIM_QUAD
output.v.edgeDistance[2] =
outpt.edgeDistance[2] =
edgeDistance(edgeVerts[index], edgeVerts[2], edgeVerts[3]);
output.v.edgeDistance[3] =
outpt.edgeDistance[3] =
edgeDistance(edgeVerts[index], edgeVerts[3], edgeVerts[0]);
#endif
@ -175,17 +176,17 @@ void main()
#endif
#ifdef PRIM_QUAD
vec3 A = (input[0].v.position - input[1].v.position).xyz;
vec3 B = (input[3].v.position - input[1].v.position).xyz;
vec3 C = (input[2].v.position - input[1].v.position).xyz;
vec3 A = (inpt[0].v.position - inpt[1].v.position).xyz;
vec3 B = (inpt[3].v.position - inpt[1].v.position).xyz;
vec3 C = (inpt[2].v.position - inpt[1].v.position).xyz;
vec3 n0 = normalize(cross(B, A));
#if defined(GEOMETRY_OUT_WIRE) || defined(GEOMETRY_OUT_LINE)
vec4 edgeVerts[EDGE_VERTS];
edgeVerts[0] = ProjectionMatrix * input[0].v.position;
edgeVerts[1] = ProjectionMatrix * input[1].v.position;
edgeVerts[2] = ProjectionMatrix * input[2].v.position;
edgeVerts[3] = ProjectionMatrix * input[3].v.position;
edgeVerts[0] = ProjectionMatrix * inpt[0].v.position;
edgeVerts[1] = ProjectionMatrix * inpt[1].v.position;
edgeVerts[2] = ProjectionMatrix * inpt[2].v.position;
edgeVerts[3] = ProjectionMatrix * inpt[3].v.position;
edgeVerts[0].xy /= edgeVerts[0].w;
edgeVerts[1].xy /= edgeVerts[1].w;
@ -205,15 +206,15 @@ void main()
#endif // PRIM_QUAD
#ifdef PRIM_TRI
vec3 A = (input[1].v.position - input[0].v.position).xyz;
vec3 B = (input[2].v.position - input[0].v.position).xyz;
vec3 A = (inpt[1].v.position - inpt[0].v.position).xyz;
vec3 B = (inpt[2].v.position - inpt[0].v.position).xyz;
vec3 n0 = normalize(cross(B, A));
#if defined(GEOMETRY_OUT_WIRE) || defined(GEOMETRY_OUT_LINE)
vec4 edgeVerts[EDGE_VERTS];
edgeVerts[0] = ProjectionMatrix * input[0].v.position;
edgeVerts[1] = ProjectionMatrix * input[1].v.position;
edgeVerts[2] = ProjectionMatrix * input[2].v.position;
edgeVerts[0] = ProjectionMatrix * inpt[0].v.position;
edgeVerts[1] = ProjectionMatrix * inpt[1].v.position;
edgeVerts[2] = ProjectionMatrix * inpt[2].v.position;
edgeVerts[0].xy /= edgeVerts[0].w;
edgeVerts[1].xy /= edgeVerts[1].w;
@ -241,7 +242,8 @@ void main()
in block {
OutputVertex v;
} input;
noperspective in vec4 edgeDistance;
} inpt;
out vec4 outColor;
@ -303,12 +305,12 @@ edgeColor(vec4 Cfill, vec4 edgeDistance)
#if defined(GEOMETRY_OUT_WIRE) || defined(GEOMETRY_OUT_LINE)
#ifdef PRIM_TRI
float d =
min(input.v.edgeDistance[0], min(input.v.edgeDistance[1], input.v.edgeDistance[2]));
min(inpt.edgeDistance[0], min(inpt.edgeDistance[1], inpt.edgeDistance[2]));
#endif
#ifdef PRIM_QUAD
float d =
min(min(input.v.edgeDistance[0], input.v.edgeDistance[1]),
min(input.v.edgeDistance[2], input.v.edgeDistance[3]));
min(min(inpt.edgeDistance[0], inpt.edgeDistance[1]),
min(inpt.edgeDistance[2], inpt.edgeDistance[3]));
#endif
vec4 Cedge = vec4(1.0, 1.0, 0.0, 1.0);
float p = exp2(-2 * d * d);
@ -326,11 +328,11 @@ edgeColor(vec4 Cfill, vec4 edgeDistance)
void
main()
{
vec3 N = (gl_FrontFacing ? input.v.normal : -input.v.normal);
vec4 Cf = lighting(input.v.position.xyz, N);
vec3 N = (gl_FrontFacing ? inpt.v.normal : -inpt.v.normal);
vec4 Cf = lighting(inpt.v.position.xyz, N);
#if defined(GEOMETRY_OUT_WIRE) || defined(GEOMETRY_OUT_LINE)
Cf = edgeColor(Cf, input.v.edgeDistance);
Cf = edgeColor(Cf, inpt.edgeDistance);
#endif
outColor = Cf;

View File

@ -131,7 +131,9 @@
#include <far/meshFactory.h>
#include <osdutil/batch.h>
#include <osdutil/batchCL.h>
#ifdef OPENSUBDIV_HAS_OPENCL
#include <osdutil/batchCL.h>
#endif
#include <osdutil/drawItem.h>
#include <osdutil/drawController.h>
#include "delegate.h"

View File

@ -65,12 +65,12 @@ layout (location=1) in vec3 normal;
out block {
OutputVertex v;
} output;
} outpt;
void main()
{
output.v.position = ModelViewMatrix * position;
output.v.normal = (ModelViewMatrix * vec4(normal, 0.0)).xyz;
outpt.v.position = ModelViewMatrix * position;
outpt.v.normal = (ModelViewMatrix * vec4(normal, 0.0)).xyz;
}
#endif
@ -90,7 +90,7 @@ void main()
in block {
OutputVertex v;
} input[4];
} inpt[4];
#endif // PRIM_QUAD
@ -104,7 +104,7 @@ void main()
in block {
OutputVertex v;
} input[3];
} inpt[3];
#endif // PRIM_TRI
@ -115,23 +115,24 @@ void main()
in block {
OutputVertex v;
} input[1];
} inpt[1];
#endif // PRIM_POINT
out block {
OutputVertex v;
} output;
noperspective out vec4 edgeDistance;
} outpt;
void emit(int index, vec3 normal)
{
output.v.position = input[index].v.position;
outpt.v.position = inpt[index].v.position;
#ifdef SMOOTH_NORMALS
output.v.normal = input[index].v.normal;
outpt.v.normal = inpt[index].v.normal;
#else
output.v.normal = normal;
outpt.v.normal = normal;
#endif
gl_Position = ProjectionMatrix * input[index].v.position;
gl_Position = ProjectionMatrix * inpt[index].v.position;
EmitVertex();
}
@ -147,18 +148,18 @@ float edgeDistance(vec4 p, vec4 p0, vec4 p1)
void emit(int index, vec3 normal, vec4 edgeVerts[EDGE_VERTS])
{
output.v.edgeDistance[0] =
outpt.edgeDistance[0] =
edgeDistance(edgeVerts[index], edgeVerts[0], edgeVerts[1]);
output.v.edgeDistance[1] =
outpt.edgeDistance[1] =
edgeDistance(edgeVerts[index], edgeVerts[1], edgeVerts[2]);
#ifdef PRIM_TRI
output.v.edgeDistance[2] =
outpt.edgeDistance[2] =
edgeDistance(edgeVerts[index], edgeVerts[2], edgeVerts[0]);
#endif
#ifdef PRIM_QUAD
output.v.edgeDistance[2] =
outpt.edgeDistance[2] =
edgeDistance(edgeVerts[index], edgeVerts[2], edgeVerts[3]);
output.v.edgeDistance[3] =
outpt.edgeDistance[3] =
edgeDistance(edgeVerts[index], edgeVerts[3], edgeVerts[0]);
#endif
@ -175,17 +176,17 @@ void main()
#endif
#ifdef PRIM_QUAD
vec3 A = (input[0].v.position - input[1].v.position).xyz;
vec3 B = (input[3].v.position - input[1].v.position).xyz;
vec3 C = (input[2].v.position - input[1].v.position).xyz;
vec3 A = (inpt[0].v.position - inpt[1].v.position).xyz;
vec3 B = (inpt[3].v.position - inpt[1].v.position).xyz;
vec3 C = (inpt[2].v.position - inpt[1].v.position).xyz;
vec3 n0 = normalize(cross(B, A));
#if defined(GEOMETRY_OUT_WIRE) || defined(GEOMETRY_OUT_LINE)
vec4 edgeVerts[EDGE_VERTS];
edgeVerts[0] = ProjectionMatrix * input[0].v.position;
edgeVerts[1] = ProjectionMatrix * input[1].v.position;
edgeVerts[2] = ProjectionMatrix * input[2].v.position;
edgeVerts[3] = ProjectionMatrix * input[3].v.position;
edgeVerts[0] = ProjectionMatrix * inpt[0].v.position;
edgeVerts[1] = ProjectionMatrix * inpt[1].v.position;
edgeVerts[2] = ProjectionMatrix * inpt[2].v.position;
edgeVerts[3] = ProjectionMatrix * inpt[3].v.position;
edgeVerts[0].xy /= edgeVerts[0].w;
edgeVerts[1].xy /= edgeVerts[1].w;
@ -205,15 +206,15 @@ void main()
#endif // PRIM_QUAD
#ifdef PRIM_TRI
vec3 A = (input[1].v.position - input[0].v.position).xyz;
vec3 B = (input[2].v.position - input[0].v.position).xyz;
vec3 A = (inpt[1].v.position - inpt[0].v.position).xyz;
vec3 B = (inpt[2].v.position - inpt[0].v.position).xyz;
vec3 n0 = normalize(cross(B, A));
#if defined(GEOMETRY_OUT_WIRE) || defined(GEOMETRY_OUT_LINE)
vec4 edgeVerts[EDGE_VERTS];
edgeVerts[0] = ProjectionMatrix * input[0].v.position;
edgeVerts[1] = ProjectionMatrix * input[1].v.position;
edgeVerts[2] = ProjectionMatrix * input[2].v.position;
edgeVerts[0] = ProjectionMatrix * inpt[0].v.position;
edgeVerts[1] = ProjectionMatrix * inpt[1].v.position;
edgeVerts[2] = ProjectionMatrix * inpt[2].v.position;
edgeVerts[0].xy /= edgeVerts[0].w;
edgeVerts[1].xy /= edgeVerts[1].w;
@ -241,7 +242,8 @@ void main()
in block {
OutputVertex v;
} input;
noperspective in vec4 edgeDistance;
} inpt;
out vec4 outColor;
@ -303,12 +305,12 @@ edgeColor(vec4 Cfill, vec4 edgeDistance)
#if defined(GEOMETRY_OUT_WIRE) || defined(GEOMETRY_OUT_LINE)
#ifdef PRIM_TRI
float d =
min(input.v.edgeDistance[0], min(input.v.edgeDistance[1], input.v.edgeDistance[2]));
min(inpt.edgeDistance[0], min(inpt.edgeDistance[1], inpt.edgeDistance[2]));
#endif
#ifdef PRIM_QUAD
float d =
min(min(input.v.edgeDistance[0], input.v.edgeDistance[1]),
min(input.v.edgeDistance[2], input.v.edgeDistance[3]));
min(min(inpt.edgeDistance[0], inpt.edgeDistance[1]),
min(inpt.edgeDistance[2], inpt.edgeDistance[3]));
#endif
vec4 Cedge = vec4(1.0, 1.0, 0.0, 1.0);
float p = exp2(-2 * d * d);
@ -326,11 +328,11 @@ edgeColor(vec4 Cfill, vec4 edgeDistance)
void
main()
{
vec3 N = (gl_FrontFacing ? input.v.normal : -input.v.normal);
vec4 Cf = lighting(input.v.position.xyz, N);
vec3 N = (gl_FrontFacing ? inpt.v.normal : -inpt.v.normal);
vec4 Cf = lighting(inpt.v.position.xyz, N);
#if defined(GEOMETRY_OUT_WIRE) || defined(GEOMETRY_OUT_LINE)
Cf = edgeColor(Cf, input.v.edgeDistance);
Cf = edgeColor(Cf, inpt.edgeDistance);
#endif
outColor = Cf;

View File

@ -693,7 +693,7 @@ createOsdMesh( const std::string &shape, int level, int kernel, Scheme scheme=kC
#endif
#ifdef OPENSUBDIV_HAS_GLSL_TRANSFORM_FEEDBACK
} else if(kernel == kGLSL) {
if (not g_glslComputeController) {
if (not g_glslTransformFeedbackComputeController) {
g_glslTransformFeedbackComputeController = new OpenSubdiv::OsdGLSLTransformFeedbackComputeController();
}
g_mesh = new OpenSubdiv::OsdMesh<OpenSubdiv::OsdGLVertexBuffer,
@ -1269,7 +1269,7 @@ display() {
GLuint diffuseColor = glGetUniformLocation(program, "diffuseColor");
if (g_displayPatchColor) {
if (g_displayPatchColor and primType == GL_PATCHES) {
float const * color = getAdaptivePatchColor( desc );
glProgramUniform4f(program, diffuseColor, color[0], color[1], color[2], color[3]);
} else {
@ -1670,7 +1670,7 @@ initHUD()
}
for (int i = 0; i < (int)g_defaultShapes.size(); ++i) {
g_hud.AddRadioButton(4, g_defaultShapes[i].name.c_str(), i==0, -220, 10+i*16, callbackModel, i, 'n');
g_hud.AddRadioButton(4, g_defaultShapes[i].name.c_str(), i==g_currentShape, -220, 10+i*16, callbackModel, i, 'n');
}
}

View File

@ -127,7 +127,8 @@ struct SimpleShape {
std::vector<SimpleShape> g_defaultShapes;
std::vector<float> g_orgPositions,
g_positions;
g_positions,
g_varyingColors;
int g_currentShape = 0,
g_level = 3,
@ -137,12 +138,17 @@ std::vector<int> g_coarseEdges;
std::vector<float> g_coarseEdgeSharpness;
std::vector<float> g_coarseVertexSharpness;
enum DrawMode { kUV=0,
kVARYING=1,
kFACEVARYING=2 };
int g_running = 1,
g_width = 1024,
g_height = 1024,
g_fullscreen = 0,
g_drawCageEdges = 1,
g_drawCageVertices = 0,
g_drawCageVertices = 1,
g_drawMode = kUV,
g_prev_x = 0,
g_prev_y = 0,
g_mbutton[3] = {0, 0, 0},
@ -285,29 +291,6 @@ GLuint g_cageEdgeVAO = 0,
GLhud g_hud;
//------------------------------------------------------------------------------
static void
createCoarseMesh( OsdHbrMesh * const hmesh, int nfaces ) {
// save coarse topology (used for coarse mesh drawing)
g_coarseEdges.clear();
g_coarseEdgeSharpness.clear();
g_coarseVertexSharpness.clear();
for(int i=0; i<nfaces; ++i) {
OsdHbrFace *face = hmesh->GetFace(i);
int nv = face->GetNumVertices();
for(int j=0; j<nv; ++j) {
g_coarseEdges.push_back(face->GetVertex(j)->GetID());
g_coarseEdges.push_back(face->GetVertex((j+1)%nv)->GetID());
g_coarseEdgeSharpness.push_back(face->GetEdge(j)->GetSharpness());
}
}
int nv = hmesh->GetNumVertices();
for(int i=0; i<nv; ++i) {
g_coarseVertexSharpness.push_back(hmesh->GetVertex(i)->GetSharpness());
}
}
//------------------------------------------------------------------------------
static int
createRandomSamples( int nfaces, int nsamples, std::vector<OsdEvalCoords> & coords ) {
@ -331,6 +314,51 @@ createRandomSamples( int nfaces, int nsamples, std::vector<OsdEvalCoords> & coor
return (int)coords.size();
}
//------------------------------------------------------------------------------
static int
createRandomVaryingColors( int nverts, std::vector<float> & colors ) {
colors.resize( nverts * 3 );
// large Pell prime number
srand( static_cast<int>(2147483647) );
for (int i=0; i<nverts; ++i) {
colors[i*3+0] = (float)rand()/(float)RAND_MAX;
colors[i*3+1] = (float)rand()/(float)RAND_MAX;
colors[i*3+2] = (float)rand()/(float)RAND_MAX;
}
return (int)colors.size();
}
//------------------------------------------------------------------------------
static void
createCoarseMesh( OsdHbrMesh * const hmesh, int nfaces ) {
// save coarse topology (used for coarse mesh drawing)
g_coarseEdges.clear();
g_coarseEdgeSharpness.clear();
g_coarseVertexSharpness.clear();
for(int i=0; i<nfaces; ++i) {
OsdHbrFace *face = hmesh->GetFace(i);
int nv = face->GetNumVertices();
for(int j=0; j<nv; ++j) {
g_coarseEdges.push_back(face->GetVertex(j)->GetID());
g_coarseEdges.push_back(face->GetVertex((j+1)%nv)->GetID());
g_coarseEdgeSharpness.push_back(face->GetEdge(j)->GetSharpness());
}
}
int nv = hmesh->GetNumVertices();
for(int i=0; i<nv; ++i) {
g_coarseVertexSharpness.push_back(hmesh->GetVertex(i)->GetSharpness());
}
// assign a randomly generated color for each vertex ofthe mesh
createRandomVaryingColors(nv, g_varyingColors);
}
//------------------------------------------------------------------------------
static int
getNumPtexFaces( OsdHbrMesh const * hmesh, int nfaces ) {
@ -359,7 +387,10 @@ OsdCpuEvalLimitContext * g_evalCtx = 0;
OsdCpuEvalLimitController g_evalCtrl;
OsdVertexBufferDescriptor g_idesc( /*offset*/ 0, /*legnth*/ 3, /*stride*/ 3 ),
g_odesc( /*offset*/ 0, /*legnth*/ 3, /*stride*/ 6 );
g_odesc( /*offset*/ 0, /*legnth*/ 3, /*stride*/ 6 ),
g_vdesc( /*offset*/ 3, /*legnth*/ 3, /*stride*/ 6 ),
g_fvidesc( /*offset*/ 0, /*legnth*/ 2, /*stride*/ 2 ),
g_fvodesc( /*offset*/ 3, /*legnth*/ 2, /*stride*/ 6 );
std::vector<OsdEvalCoords> g_coords;
@ -395,7 +426,7 @@ updateGeom() {
g_vertexData->UpdateData( &g_positions[0], 0, nverts);
g_computeCtrl.Refine( g_computeCtx, g_fmesh->GetKernelBatches(), g_vertexData );
g_computeCtrl.Refine( g_computeCtx, g_fmesh->GetKernelBatches(), g_vertexData, g_varyingData );
s.Stop();
g_computeTime = float(s.GetElapsed() * 1000.0f);
@ -406,14 +437,25 @@ updateGeom() {
s.Start();
// Reset the output buffer
float * cpubuff = g_Q->BindCpuBuffer();
memset( cpubuff, 0, g_Q->GetNumVertices()*g_Q->GetNumElements()*sizeof(float) );
g_nsamplesFound=0;
// Bind/Unbind of the vertex buffers to the context needs to happen
// outside of the parallel loop
g_evalCtx->BindVertexBuffers( g_idesc, g_vertexData, g_odesc, g_Q, g_dQu, g_dQv );
g_evalCtx->GetVertexData().Bind( g_idesc, g_vertexData, g_odesc, g_Q, g_dQu, g_dQv );
// The varying data ends-up interleaved in the same g_Q output buffer because
// g_Q has a stride of 6 and g_vdesc sets the offset to 3, while g_odesc sets
// the offset to 0
switch (g_drawMode) {
case kVARYING : g_evalCtx->GetVaryingData().Bind( g_idesc, g_varyingData, g_vdesc, g_Q ); break;
case kFACEVARYING : g_evalCtx->GetFaceVaryingData().Bind( g_fvidesc, g_fvodesc, g_Q );
case kUV :
default : g_evalCtx->GetVaryingData().Unbind(); break;
}
#define USE_OPENMP
#if defined(OPENSUBDIV_HAS_OPENMP) and defined(USE_OPENMP)
@ -424,22 +466,39 @@ updateGeom() {
int n = g_evalCtrl.EvalLimitSample<OsdCpuVertexBuffer,OsdCpuGLVertexBuffer>( g_coords[i], g_evalCtx, i );
if (n) {
// point colors
float * color = cpubuff + i * 6 + 3;
switch (g_drawMode) {
case kUV : { float * color = g_Q->BindCpuBuffer() + i*g_Q->GetNumElements() + 3;
color[0] = g_coords[i].u;
color[1] = 0.0f;
color[2] = g_coords[i].v; } break;
color[0] = g_coords[i].u;
color[1] = 0.0f;
color[2] = g_coords[i].v;
case kVARYING : break;
case kFACEVARYING : break;
default : break;
}
#if defined(OPENSUBDIV_HAS_OPENMP) and defined(USE_OPENMP)
#pragma omp atomic
#endif
g_nsamplesFound += n;
} else {
// "hide" unfound samples (hole tags...) as a black dot at the origin
float * sample = g_Q->BindCpuBuffer() + i*g_Q->GetNumElements();
memset(sample, 0, g_Q->GetNumElements() * sizeof(float));
}
}
g_evalCtx->UnbindVertexBuffers();
g_evalCtx->GetVertexData().Unbind();
switch (g_drawMode) {
case kVARYING : g_evalCtx->GetVaryingData().Unbind(); break;
case kFACEVARYING : g_evalCtx->GetFaceVaryingData().Unbind(); break;
default : break;
}
g_Q->BindVBO();
@ -453,7 +512,7 @@ static void
createOsdMesh( const std::string &shape, int level, Scheme scheme=kCatmark ) {
// Create HBR mesh
OsdHbrMesh * hmesh = simpleHbr<OsdVertex>(shape.c_str(), scheme, g_orgPositions);
OsdHbrMesh * hmesh = simpleHbr<OsdVertex>(shape.c_str(), scheme, g_orgPositions, true);
g_positions.resize(g_orgPositions.size(),0.0f);
@ -465,13 +524,11 @@ createOsdMesh( const std::string &shape, int level, Scheme scheme=kCatmark ) {
createCoarseMesh(hmesh, nfaces);
// Create FAR mesh
OsdFarMeshFactory factory( hmesh, level, /*adaptive*/ true);
delete g_fmesh;
g_fmesh = factory.Create(/*fvar*/ false);
g_fmesh = factory.Create(/*fvar*/ true);
int nverts = g_fmesh->GetNumVertices();
@ -481,32 +538,36 @@ createOsdMesh( const std::string &shape, int level, Scheme scheme=kCatmark ) {
delete g_vertexData;
g_vertexData = OsdCpuVertexBuffer::Create(3, nverts);
// Create v-buffer & populate w/ colors
delete g_varyingData;
g_varyingData = OsdCpuVertexBuffer::Create(3, nverts);
// Create primvar v-buffer & populate w/ colors or (u,v) data
delete g_varyingData; g_varyingData = 0;
if (g_drawMode==kVARYING) {
g_varyingData = OsdCpuVertexBuffer::Create(3, nverts);
g_varyingData->UpdateData( &g_varyingColors[0], 0, nverts);
}
// Create a Compute context, used to "pose" the vertices
delete g_computeCtx;
g_computeCtx = OsdCpuComputeContext::Create(g_fmesh);
g_computeCtrl.Refine( g_computeCtx, g_fmesh->GetKernelBatches(), g_vertexData );
g_computeCtrl.Refine( g_computeCtx, g_fmesh->GetKernelBatches(), g_vertexData, g_varyingData );
// Create eval context & data buffers
delete g_evalCtx;
g_evalCtx = OsdCpuEvalLimitContext::Create(g_fmesh);
g_evalCtx = OsdCpuEvalLimitContext::Create(g_fmesh, /*requireFVarData*/ true);
delete g_Q;
g_Q = OsdCpuGLVertexBuffer::Create(6,nsamples);
memset( g_Q->BindCpuBuffer(), 0, nsamples*6*sizeof(float));
delete g_dQu;
g_dQu = OsdCpuGLVertexBuffer::Create(6,nsamples);
memset( g_dQu->BindCpuBuffer(), 0, nsamples*6*sizeof(float));
delete g_dQv;
g_dQv = OsdCpuGLVertexBuffer::Create(6,nsamples);
memset( g_dQv->BindCpuBuffer(), 0, nsamples*6*sizeof(float));
updateGeom();
@ -686,7 +747,20 @@ drawCageVertices() {
vbo.reserve(numPoints*6);
float r, g, b;
for (int i = 0; i < numPoints; ++i) {
setSharpnessColor(g_coarseVertexSharpness[i], &r, &g, &b);
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]);
@ -729,7 +803,7 @@ drawSamples() {
glBindVertexArray(g_samplesVAO);
glPointSize(1.0f);
glDrawArrays( GL_POINTS, 0, (int)g_coords.size() );
glDrawArrays( GL_POINTS, 0, (int)g_coords.size());
glPointSize(1.0f);
glBindVertexArray(0);
@ -787,7 +861,12 @@ display() {
g_hud.DrawString(10, -60, "GPU Draw : %.3f ms", drawGpuTime);
g_hud.DrawString(10, -40, "CPU Draw : %.3f ms", drawCpuTime);
g_hud.DrawString(10, -20, "FPS : %3.1f", fps);
if (g_drawMode==kFACEVARYING and g_evalCtx->GetFVarData().empty()) {
static char msg[21] = "No Face-Varying Data";
g_hud.DrawString(g_width/2-20/2*8, g_height/2, msg);
}
g_hud.Flush();
}
@ -957,14 +1036,43 @@ 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
callbackDisplayVaryingColors(int mode)
{
g_drawMode = mode;
createOsdMesh( g_defaultShapes[g_currentShape].data, g_level, g_defaultShapes[ g_currentShape ].scheme );
}
//------------------------------------------------------------------------------
static void
initHUD()
{
g_hud.Init(g_width, g_height);
g_hud.AddCheckBox("Animate vertices (M)", g_moveScale != 0, 350, 20, callbackAnimate, 0, 'm');
g_hud.AddCheckBox("Freeze (spc)", false, 350, 40, callbackFreeze, 0, ' ');
g_hud.AddCheckBox("Cage Edges (H)", true, 350, 10, callbackDisplayCageEdges, 0, 'h');
g_hud.AddCheckBox("Cage Verts (J)", true, 350, 30, callbackDisplayCageVertices, 0, 'j');
g_hud.AddCheckBox("Animate vertices (M)", g_moveScale != 0, 350, 50, callbackAnimate, 0, 'm');
g_hud.AddCheckBox("Freeze (spc)", false, 350, 70, callbackFreeze, 0, ' ');
g_hud.AddRadioButton(0, "(u,v)", true, 200, 10, callbackDisplayVaryingColors, kUV, 'k');
g_hud.AddRadioButton(0, "varying", false, 200, 30, callbackDisplayVaryingColors, kVARYING, 'k');
g_hud.AddRadioButton(0, "face-varying", false, 200, 50, callbackDisplayVaryingColors, kFACEVARYING, 'k');
for (int i = 1; i < 11; ++i) {
char level[16];

View File

@ -94,11 +94,11 @@ vec4 PTexLookup(vec4 patchCoord,
#ifdef USE_PTEX_DISPLACEMENT
#define OSD_DISPLACEMENT_CALLBACK \
output.v.position = \
displacement(output.v.position, \
output.v.normal, \
output.v.patchCoord);
#define OSD_DISPLACEMENT_CALLBACK \
outpt.v.position = \
displacement(outpt.v.position, \
outpt.v.normal, \
outpt.v.patchCoord);
uniform sampler2DArray textureDisplace_Data;
uniform samplerBuffer textureDisplace_Packing;
@ -124,12 +124,12 @@ layout (location=1) in vec3 normal;
out block {
OutputVertex v;
} output;
} outpt;
void main()
{
output.v.position = vec4(position, 1);
output.v.normal = normal;
outpt.v.position = vec4(position, 1);
outpt.v.normal = normal;
}
#endif // VERTEX_SHADER
@ -153,7 +153,7 @@ void main()
in block {
OutputVertex v;
} input[4];
} inpt[4];
#endif // PRIM_QUAD
@ -171,23 +171,23 @@ void main()
in block {
OutputVertex v;
} input[3];
} inpt[3];
#endif // PRIM_TRI
out block {
OutputVertex v;
} output;
} outpt;
void emit(int index, vec4 position, vec3 normal, vec4 patchCoord)
{
output.v.position = position;
output.v.normal = normal;
output.v.patchCoord = patchCoord;
outpt.v.position = position;
outpt.v.normal = normal;
outpt.v.patchCoord = patchCoord;
output.v.tangent = input[index].v.tangent;
outpt.v.tangent = inpt[index].v.tangent;
gl_Position = ProjectionMatrix * output.v.position;
gl_Position = ProjectionMatrix * outpt.v.position;
EmitVertex();
}
@ -210,15 +210,15 @@ void main()
patchCoord[3] = GeneratePatchCoord(vec2(0, 1));
#ifdef USE_PTEX_DISPLACEMENT
position[0] = displacement(input[0].v.position, input[0].v.normal, patchCoord[0]);
position[1] = displacement(input[1].v.position, input[1].v.normal, patchCoord[1]);
position[2] = displacement(input[2].v.position, input[2].v.normal, patchCoord[2]);
position[3] = displacement(input[3].v.position, input[3].v.normal, patchCoord[3]);
position[0] = displacement(inpt[0].v.position, inpt[0].v.normal, patchCoord[0]);
position[1] = displacement(inpt[1].v.position, inpt[1].v.normal, patchCoord[1]);
position[2] = displacement(inpt[2].v.position, inpt[2].v.normal, patchCoord[2]);
position[3] = displacement(inpt[3].v.position, inpt[3].v.normal, patchCoord[3]);
#else
position[0] = input[0].v.position;
position[1] = input[1].v.position;
position[2] = input[2].v.position;
position[3] = input[3].v.position;
position[0] = inpt[0].v.position;
position[1] = inpt[1].v.position;
position[2] = inpt[2].v.position;
position[3] = inpt[3].v.position;
#endif
#ifdef FLAT_NORMALS
@ -231,10 +231,10 @@ void main()
normal[2] = normal[0];
normal[3] = normal[0];
#else
normal[0] = input[0].v.normal;
normal[1] = input[1].v.normal;
normal[2] = input[2].v.normal;
normal[3] = input[3].v.normal;
normal[0] = inpt[0].v.normal;
normal[1] = inpt[1].v.normal;
normal[2] = inpt[2].v.normal;
normal[3] = inpt[3].v.normal;
#endif
emit(0, position[0], normal[0], patchCoord[0]);
@ -257,18 +257,18 @@ void main()
vec3 normal[3];
// patch coords are computed in tessellation shader
patchCoord[0] = input[0].v.patchCoord;
patchCoord[1] = input[1].v.patchCoord;
patchCoord[2] = input[2].v.patchCoord;
patchCoord[0] = inpt[0].v.patchCoord;
patchCoord[1] = inpt[1].v.patchCoord;
patchCoord[2] = inpt[2].v.patchCoord;
#ifdef USE_PTEX_DISPLACEMENT
position[0] = displacement(input[0].v.position, input[0].v.normal, patchCoord[0]);
position[1] = displacement(input[1].v.position, input[1].v.normal, patchCoord[1]);
position[2] = displacement(input[2].v.position, input[2].v.normal, patchCoord[2]);
position[0] = displacement(inpt[0].v.position, inpt[0].v.normal, patchCoord[0]);
position[1] = displacement(inpt[1].v.position, inpt[1].v.normal, patchCoord[1]);
position[2] = displacement(inpt[2].v.position, inpt[2].v.normal, patchCoord[2]);
#else
position[0] = input[0].v.position;
position[1] = input[1].v.position;
position[2] = input[2].v.position;
position[0] = inpt[0].v.position;
position[1] = inpt[1].v.position;
position[2] = inpt[2].v.position;
#endif
#ifdef FLAT_NORMALS // emit flat normals for displaced surface
@ -278,9 +278,9 @@ void main()
normal[1] = normal[0];
normal[2] = normal[0];
#else
normal[0] = input[0].v.normal;
normal[1] = input[1].v.normal;
normal[2] = input[2].v.normal;
normal[0] = inpt[0].v.normal;
normal[1] = inpt[1].v.normal;
normal[2] = inpt[2].v.normal;
#endif
emit(0, position[0], normal[0], patchCoord[0]);
@ -303,7 +303,7 @@ void main()
in block {
OutputVertex v;
} input;
} inpt;
uniform int ptexFaceOffset;
@ -398,7 +398,7 @@ void
main()
{
#ifdef USE_PTEX_COLOR
vec4 texColor = PTexLookup(input.v.patchCoord,
vec4 texColor = PTexLookup(inpt.v.patchCoord,
textureImage_Data,
textureImage_Packing,
textureImage_Pages);
@ -407,16 +407,16 @@ main()
#endif
#if USE_PTEX_NORMAL
vec3 objN = perturbNormalFromDisplacement(input.v.position.xyz,
input.v.normal,
input.v.patchCoord);
vec3 objN = perturbNormalFromDisplacement(inpt.v.position.xyz,
inpt.v.normal,
inpt.v.patchCoord);
#else
vec3 objN = input.v.normal;
vec3 objN = inpt.v.normal;
#endif
#ifdef USE_PTEX_OCCLUSION
float occ = PTexLookup(input.v.patchCoord,
float occ = PTexLookup(inpt.v.patchCoord,
textureOcclusion_Data,
textureOcclusion_Packing,
textureOcclusion_Pages).x;
@ -432,7 +432,7 @@ main()
vec4 d = vec4(1);
#endif
vec3 eye = normalize(input.v.position.xyz - eyePositionInWorld);
vec3 eye = normalize(inpt.v.position.xyz - eyePositionInWorld);
#ifdef USE_SPECULAR_ENV_MAP
vec3 reflect = reflect(eye, objN);

View File

@ -131,13 +131,11 @@ static const char *defaultShaderSource =
// Draw styles for EffectDrawRegistry
enum Effect
{
kQuadFill = 0,
kQuadLine = 1,
kTriFill = 2,
kTriLine = 3,
kPoint = 4,
kFill = 0,
kLine = 1,
kPoint = 2,
};
typedef std::pair<OpenSubdiv::OsdPatchDescriptor, Effect> EffectDesc;
typedef std::pair<OpenSubdiv::OsdDrawContext::PatchDescriptor, Effect> EffectDesc;
// #### Override of OpenSubdiv::OsdGLDrawRegistry
//
@ -214,17 +212,20 @@ EffectDrawRegistry::_CreateDrawSourceConfig(DescType const & desc)
SourceConfigType * sconfig =
BaseRegistry::_CreateDrawSourceConfig(desc.first);
if (desc.first.type != OpenSubdiv::kNonPatch) {
// Per-vertex descriptors are use for uniform refinement
if (effect == kQuadFill) effect = kTriFill;
if (effect == kQuadLine) effect = kTriLine;
sconfig->geometryShader.AddDefine("SMOOTH_NORMALS");
} else {
bool quad = false;
if (desc.first.GetType() == OpenSubdiv::FarPatchTables::QUADS) {
// Configuration for adaptive refinement
sconfig->vertexShader.version = "#version 410\n";
sconfig->vertexShader.source = _shaderSource;
sconfig->vertexShader.AddDefine("VERTEX_SHADER");
quad = true;
} else if (desc.first.GetType() == OpenSubdiv::FarPatchTables::TRIANGLES) {
sconfig->vertexShader.version = "#version 410\n";
sconfig->vertexShader.source = _shaderSource;
sconfig->vertexShader.AddDefine("VERTEX_SHADER");
} else {
// adaptive patches
sconfig->geometryShader.AddDefine("SMOOTH_NORMALS");
}
assert(sconfig);
@ -254,29 +255,20 @@ EffectDrawRegistry::_CreateDrawSourceConfig(DescType const & desc)
sconfig->fragmentShader.AddDefine("FRAGMENT_SHADER");
// Set up directives according to draw style
if (quad) {
sconfig->geometryShader.AddDefine("PRIM_QUAD");
sconfig->fragmentShader.AddDefine("PRIM_QUAD");
} else {
sconfig->geometryShader.AddDefine("PRIM_TRI");
sconfig->fragmentShader.AddDefine("PRIM_TRI");
}
switch (effect) {
case kQuadFill:
sconfig->geometryShader.AddDefine("PRIM_QUAD");
case kFill:
sconfig->geometryShader.AddDefine("GEOMETRY_OUT_FILL");
sconfig->fragmentShader.AddDefine("PRIM_QUAD");
sconfig->fragmentShader.AddDefine("GEOMETRY_OUT_FILL");
break;
case kQuadLine:
sconfig->geometryShader.AddDefine("PRIM_QUAD");
case kLine:
sconfig->geometryShader.AddDefine("GEOMETRY_OUT_LINE");
sconfig->fragmentShader.AddDefine("PRIM_QUAD");
sconfig->fragmentShader.AddDefine("GEOMETRY_OUT_LINE");
break;
case kTriFill:
sconfig->geometryShader.AddDefine("PRIM_TRI");
sconfig->geometryShader.AddDefine("GEOMETRY_OUT_FILL");
sconfig->fragmentShader.AddDefine("PRIM_TRI");
sconfig->fragmentShader.AddDefine("GEOMETRY_OUT_FILL");
break;
case kTriLine:
sconfig->geometryShader.AddDefine("PRIM_TRI");
sconfig->geometryShader.AddDefine("GEOMETRY_OUT_LINE");
sconfig->fragmentShader.AddDefine("PRIM_TRI");
sconfig->fragmentShader.AddDefine("GEOMETRY_OUT_LINE");
break;
case kPoint:
@ -344,7 +336,7 @@ EffectDrawRegistry::_CreateDrawConfig(
if ((loc = glGetUniformLocation(config->program, "g_QuadOffsetBuffer")) != -1) {
glProgramUniform1i(config->program, loc, 2); // GL_TEXTURE2
}
if ((loc = glGetUniformLocation(config->program, "g_patchLevelBuffer")) != -1) {
if ((loc = glGetUniformLocation(config->program, "g_ptexIndicesBuffer")) != -1) {
glProgramUniform1i(config->program, loc, 3); // GL_TEXTURE3
}
if ((loc = glGetUniformLocation(config->program, "g_uvFVarBuffer")) != -1) {
@ -668,31 +660,36 @@ OpenSubdivShader::draw(const MHWRender::MDrawContext &mDrawContext,
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 3, 0);
glEnableVertexAttribArray(0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, osdDrawContext->patchIndexBuffer);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, osdDrawContext->GetPatchIndexBuffer());
// Get list of patches from OSD
OpenSubdiv::OsdPatchArrayVector const & patches =
OpenSubdiv::OsdDrawContext::PatchArrayVector const & patches =
osdDrawContext->patchArrays;
// Draw patches
for (size_t i = 0; i < patches.size(); ++i) {
OpenSubdiv::OsdPatchArray const & patch = patches[i];
OpenSubdiv::OsdDrawContext::PatchArray const & patch = patches[i];
bindProgram(mDrawContext, osdDrawContext, patch);
GLuint program = bindProgram(mDrawContext, osdDrawContext, patch);
if (patch.desc.type != OpenSubdiv::kNonPatch) {
glPatchParameteri(GL_PATCH_VERTICES, patch.desc.GetPatchSize());
GLuint uniformGregoryQuadOffset = glGetUniformLocation(program, "GregoryQuadOffsetBase");
GLuint uniformLevelBase = glGetUniformLocation(program, "LevelBase");
glProgramUniform1i(program, uniformGregoryQuadOffset, patch.GetQuadOffsetIndex());
glProgramUniform1i(program, uniformLevelBase, patch.GetPatchIndex());
glDrawElements(GL_PATCHES,
patch.numIndices, GL_UNSIGNED_INT,
reinterpret_cast<void *>(patch.firstIndex *
sizeof(unsigned int)));
} else {
glDrawElements(_scheme == OsdMeshData::kLoop ? GL_TRIANGLES : GL_LINES_ADJACENCY,
patch.numIndices, GL_UNSIGNED_INT,
reinterpret_cast<void *>(patch.firstIndex *
sizeof(unsigned int)));
GLenum primType = GL_PATCHES;
if (patch.GetDescriptor().GetType() == OpenSubdiv::FarPatchTables::QUADS) {
primType = GL_LINES_ADJACENCY;
} else if (patch.GetDescriptor().GetType() == OpenSubdiv::FarPatchTables::TRIANGLES) {
primType = GL_TRIANGLES;
} else if (patch.GetDescriptor().GetType() >= OpenSubdiv::FarPatchTables::REGULAR) {
glPatchParameteri(GL_PATCH_VERTICES, patch.GetDescriptor().GetNumControlVertices());
}
glDrawElements(primType,
patch.GetNumIndices(), GL_UNSIGNED_INT,
reinterpret_cast<void *>(patch.GetVertIndex() *
sizeof(unsigned int)));
CHECK_GL_ERROR("post draw\n");
}
@ -782,14 +779,14 @@ OpenSubdivShader::updateRegistry()
GLuint
OpenSubdivShader::bindProgram(const MHWRender::MDrawContext & mDrawContext,
OpenSubdiv::OsdGLDrawContext *osdDrawContext,
const OpenSubdiv::OsdPatchArray & patch)
const OpenSubdiv::OsdDrawContext::PatchArray & patch)
{
CHECK_GL_ERROR("bindProgram begin\n");
// Primitives are triangles for Loop subdivision, quads otherwise
Effect effect = (_scheme == OsdMeshData::kLoop) ? kTriFill : kQuadFill;
EffectDesc effectDesc( patch.desc, effect );
Effect effect = kFill;
EffectDesc effectDesc( patch.GetDescriptor(), effect );
// Build shader
EffectDrawRegistry::ConfigType *
@ -828,13 +825,9 @@ OpenSubdivShader::bindProgram(const MHWRender::MDrawContext & mDrawContext,
// Update and bind tessellation state
struct Tessellation {
float TessLevel;
int GregoryQuadOffsetBase;
int LevelBase;
} tessellationData;
tessellationData.TessLevel = static_cast<float>(1 << _tessFactor);
tessellationData.GregoryQuadOffsetBase = patch.gregoryQuadOffsetBase;
tessellationData.LevelBase = patch.levelBase;
if (!g_tessellationUB) {
glGenBuffers(1, &g_tessellationUB);
@ -932,30 +925,30 @@ OpenSubdivShader::bindProgram(const MHWRender::MDrawContext & mDrawContext,
// GL texture buffers. These are managed by the DrawContext
// and must be bound for use by the program in addition to
// any buffers used by the client/application shading code.
if (osdDrawContext->vertexTextureBuffer) {
if (osdDrawContext->GetVertexTextureBuffer()) {
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_BUFFER,
osdDrawContext->vertexTextureBuffer);
osdDrawContext->GetVertexTextureBuffer());
}
if (osdDrawContext->vertexValenceTextureBuffer) {
if (osdDrawContext->GetVertexValenceTextureBuffer()) {
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_BUFFER,
osdDrawContext->vertexValenceTextureBuffer);
osdDrawContext->GetVertexValenceTextureBuffer());
}
if (osdDrawContext->quadOffsetTextureBuffer) {
if (osdDrawContext->GetQuadOffsetsTextureBuffer()) {
glActiveTexture(GL_TEXTURE2);
glBindTexture(GL_TEXTURE_BUFFER,
osdDrawContext->quadOffsetTextureBuffer);
osdDrawContext->GetQuadOffsetsTextureBuffer());
}
if (osdDrawContext->patchLevelTextureBuffer) {
if (osdDrawContext->GetPatchParamTextureBuffer()) {
glActiveTexture(GL_TEXTURE3);
glBindTexture(GL_TEXTURE_BUFFER,
osdDrawContext->patchLevelTextureBuffer);
osdDrawContext->GetPatchParamTextureBuffer());
}
if (osdDrawContext->fvarDataTextureBuffer) {
glActiveTexture( GL_TEXTURE4 );
glBindTexture( GL_TEXTURE_BUFFER,
osdDrawContext->fvarDataTextureBuffer );
if (osdDrawContext->GetFvarDataTextureBuffer()) {
glActiveTexture(GL_TEXTURE4);
glBindTexture(GL_TEXTURE_BUFFER,
osdDrawContext->GetFvarDataTextureBuffer() );
}
glActiveTexture(GL_TEXTURE0);

View File

@ -123,7 +123,7 @@ private:
GLuint bindTexture(const MString& filename, int textureUnit);
GLuint bindProgram(const MHWRender::MDrawContext & mDrawContext,
OpenSubdiv::OsdGLDrawContext *osdDrawContext,
const OpenSubdiv::OsdPatchArray & patch);
const OpenSubdiv::OsdDrawContext::PatchArray & patch);
// OSD attributes
static MObject aLevel;

View File

@ -65,11 +65,11 @@ layout (location=0) in vec4 position;
out block {
OutputVertex v;
} output;
} outpt;
void main()
{
output.v.position = ModelViewMatrix * position;
outpt.v.position = ModelViewMatrix * position;
}
#endif // VERTEX_SHADER
@ -95,7 +95,7 @@ uniform samplerBuffer g_uvFVarBuffer;
in block {
OutputVertex v;
} input[4];
} inpt[4];
#endif // PRIM_QUAD
@ -113,7 +113,7 @@ uniform samplerBuffer g_uvFVarBuffer;
in block {
OutputVertex v;
} input[3];
} inpt[3];
#endif // PRIM_TRI
@ -124,21 +124,21 @@ uniform samplerBuffer g_uvFVarBuffer;
in block {
OutputVertex v;
} input[1];
} inpt[1];
#endif // PRIM_POINT
out block {
OutputVertex v;
} output;
} outpt;
void emitUniform(int index, vec3 normal)
{
output.v.position = input[index].v.position;
outpt.v.position = inpt[index].v.position;
#ifdef SMOOTH_NORMALS
output.v.normal = input[index].v.normal;
outpt.v.normal = inpt[index].v.normal;
#else
output.v.normal = normal;
outpt.v.normal = normal;
#endif
// We fetch each uv component separately since the texture buffer
@ -151,31 +151,32 @@ void emitUniform(int index, vec3 normal)
// prim 0 prim 1
int uvOffset = gl_PrimitiveID * 4;
output.v.patchCoord.st =
vec2( texelFetchBuffer( g_uvFVarBuffer, (uvOffset+index)*2 ).s,
texelFetchBuffer( g_uvFVarBuffer, (uvOffset+index)*2+1 ).s );
outpt.v.patchCoord.st =
vec2( texelFetch( g_uvFVarBuffer, (uvOffset+index)*2 ).s,
texelFetch( g_uvFVarBuffer, (uvOffset+index)*2+1 ).s );
gl_Position = ProjectionMatrix * input[index].v.position;
gl_Position = ProjectionMatrix * inpt[index].v.position;
EmitVertex();
}
void emitAdaptive(int index, vec3 normal, vec2 uvs[4])
{
output.v.position = input[index].v.position;
outpt.v.position = inpt[index].v.position;
#ifdef SMOOTH_NORMALS
output.v.normal = input[index].v.normal;
outpt.v.normal = inpt[index].v.normal;
#else
output.v.normal = normal;
outpt.v.normal = normal;
#endif
// Bi-linear interpolation within the patch
vec2 st = input[index].v.patchCoord.st;
output.v.patchCoord.st =
outpt.v.patchCoord = inpt[index].v.patchCoord;
vec2 st = inpt[index].v.tessCoord;
outpt.v.patchCoord.st =
vec2( mix( mix(uvs[0].x, uvs[1].x, st.s ), mix(uvs[3].x, uvs[2].x, st.s ), st.t),
mix( mix(uvs[0].y, uvs[1].y, st.s ), mix(uvs[3].y, uvs[2].y, st.s ), st.t) );
gl_Position = ProjectionMatrix * input[index].v.position;
gl_Position = ProjectionMatrix * inpt[index].v.position;
EmitVertex();
}
@ -199,17 +200,17 @@ void main()
int uvOffset = (gl_PrimitiveID+LevelBase) * 4;
vec2 uvs[4];
uvs[0] = vec2( texelFetchBuffer( g_uvFVarBuffer, (uvOffset+0)*2 ).s,
texelFetchBuffer( g_uvFVarBuffer, (uvOffset+0)*2+1 ).s );
uvs[0] = vec2( texelFetch( g_uvFVarBuffer, (uvOffset+0)*2 ).s,
texelFetch( g_uvFVarBuffer, (uvOffset+0)*2+1 ).s );
uvs[1] = vec2( texelFetchBuffer( g_uvFVarBuffer, (uvOffset+1)*2 ).s,
texelFetchBuffer( g_uvFVarBuffer, (uvOffset+1)*2+1 ).s );
uvs[1] = vec2( texelFetch( g_uvFVarBuffer, (uvOffset+1)*2 ).s,
texelFetch( g_uvFVarBuffer, (uvOffset+1)*2+1 ).s );
uvs[2] = vec2( texelFetchBuffer( g_uvFVarBuffer, (uvOffset+2)*2 ).s,
texelFetchBuffer( g_uvFVarBuffer, (uvOffset+2)*2+1 ).s );
uvs[2] = vec2( texelFetch( g_uvFVarBuffer, (uvOffset+2)*2 ).s,
texelFetch( g_uvFVarBuffer, (uvOffset+2)*2+1 ).s );
uvs[3] = vec2( texelFetchBuffer( g_uvFVarBuffer, (uvOffset+3)*2 ).s,
texelFetchBuffer( g_uvFVarBuffer, (uvOffset+3)*2+1 ).s );
uvs[3] = vec2( texelFetch( g_uvFVarBuffer, (uvOffset+3)*2 ).s,
texelFetch( g_uvFVarBuffer, (uvOffset+3)*2+1 ).s );
#endif
vec3 n0 = vec3(0);
@ -220,8 +221,8 @@ void main()
#elif defined ( PRIM_TRI)
vec3 A = (input[1].v.position - input[0].v.position).xyz;
vec3 B = (input[2].v.position - input[0].v.position).xyz;
vec3 A = (inpt[1].v.position - inpt[0].v.position).xyz;
vec3 B = (inpt[2].v.position - inpt[0].v.position).xyz;
n0 = normalize(cross(B, A));
#ifdef FVAR_ADAPTIVE
emitAdaptive(0, n0, uvs);
@ -244,9 +245,9 @@ void main()
#elif defined ( PRIM_QUAD )
vec3 A = (input[0].v.position - input[1].v.position).xyz;
vec3 B = (input[3].v.position - input[1].v.position).xyz;
//vec3 C = (input[2].v.position - input[1].v.position).xyz;
vec3 A = (inpt[0].v.position - inpt[1].v.position).xyz;
vec3 B = (inpt[3].v.position - inpt[1].v.position).xyz;
//vec3 C = (inpt[2].v.position - inpt[1].v.position).xyz;
n0 = normalize(cross(B, A));
#ifdef GEOMETRY_OUT_FILL
@ -278,7 +279,7 @@ uniform sampler2D diffuseMap;
in block {
OutputVertex v;
} input;
} inpt;
#define NUM_LIGHTS 2
@ -348,12 +349,12 @@ main()
void
main()
{
vec3 N = (gl_FrontFacing ? input.v.normal : -input.v.normal);
vec3 N = (gl_FrontFacing ? inpt.v.normal : -inpt.v.normal);
#ifdef USE_DIFFUSE_MAP
vec4 texColor = texture(diffuseMap, input.v.patchCoord.st);
gl_FragColor = lighting(input.v.position.xyz, N, texColor);
vec4 texColor = texture(diffuseMap, inpt.v.patchCoord.st);
gl_FragColor = lighting(inpt.v.position.xyz, N, texColor);
#else
gl_FragColor = lighting(input.v.position.xyz, N, vec4(1.0));
gl_FragColor = lighting(inpt.v.position.xyz, N, vec4(1.0));
#endif
}
#endif // GEOMETRY_OUT_LINE

View File

@ -94,11 +94,11 @@ layout (location=0) in vec4 position;
out block {
OutputVertex v;
} output;
} outpt;
void main()
{
output.v.position = ModelViewMatrix * position;
outpt.v.position = ModelViewMatrix * position;
}
#endif
@ -114,19 +114,19 @@ layout(triangle_strip, max_vertices = 3) out;
in block {
OutputVertex v;
} input[3];
} inpt[3];
out block {
OutputVertex v;
vec4 depthPosition;
} output;
} outpt;
void emit(int index, vec4 position)
{
vec2 uv = vec2(input[index].v.patchCoord.xy);
output.v.position = ProjectionMatrix * position;
output.depthPosition = ProjectionWithoutPickMatrix * position;
output.v.patchCoord = input[index].v.patchCoord;
vec2 uv = vec2(inpt[index].v.patchCoord.xy);
outpt.v.position = ProjectionMatrix * position;
outpt.depthPosition = ProjectionWithoutPickMatrix * position;
outpt.v.patchCoord = inpt[index].v.patchCoord;
gl_Position = vec4(uv*2-vec2(1.0), 0, 1);
EmitVertex();
}
@ -139,18 +139,18 @@ void main()
vec4 position[3];
// patch coords are computed in tessellation shader
patchCoord[0] = input[0].v.patchCoord;
patchCoord[1] = input[1].v.patchCoord;
patchCoord[2] = input[2].v.patchCoord;
patchCoord[0] = inpt[0].v.patchCoord;
patchCoord[1] = inpt[1].v.patchCoord;
patchCoord[2] = inpt[2].v.patchCoord;
#ifdef USE_PTEX_DISPLACEMENT
position[0] = displacement(input[0].v.position, input[0].v.normal, patchCoord[0]);
position[1] = displacement(input[1].v.position, input[1].v.normal, patchCoord[1]);
position[2] = displacement(input[2].v.position, input[2].v.normal, patchCoord[2]);
position[0] = displacement(inpt[0].v.position, inpt[0].v.normal, patchCoord[0]);
position[1] = displacement(inpt[1].v.position, inpt[1].v.normal, patchCoord[1]);
position[2] = displacement(inpt[2].v.position, inpt[2].v.normal, patchCoord[2]);
#else
position[0] = input[0].v.position;
position[1] = input[1].v.position;
position[2] = input[2].v.position;
position[0] = inpt[0].v.position;
position[1] = inpt[1].v.position;
position[2] = inpt[2].v.position;
#endif
emit(0, position[0]);
@ -169,7 +169,7 @@ void main()
in block {
OutputVertex v;
vec4 depthPosition;
} input;
} inpt;
layout(size1x32) uniform image2DArray outTextureImage;
uniform sampler2D paintTexture;
@ -179,10 +179,10 @@ uniform int imageSize = 256;
void
main()
{
vec4 p = input.v.position;
vec4 p = inpt.v.position;
p.xyz /= p.w;
vec4 wp = input.depthPosition;
vec4 wp = inpt.depthPosition;
wp.z -= 0.001;
wp.xyz /= wp.w;
@ -190,9 +190,9 @@ main()
float depth = texture(depthTexture, wp.xy*0.5+0.5).x;
if (wp.z*0.5+0.5 >= depth) return;
ivec3 pos = ivec3(input.v.patchCoord.x * imageSize,
input.v.patchCoord.y * imageSize,
int(input.v.patchCoord.w));
ivec3 pos = ivec3(inpt.v.patchCoord.x * imageSize,
inpt.v.patchCoord.y * imageSize,
int(inpt.v.patchCoord.w));
vec4 d = imageLoad(outTextureImage, pos);
c = c + d;

View File

@ -97,19 +97,20 @@ vec4 displacement(vec4 position, vec3 normal, vec4 patchCoord)
in block {
OutputVertex v;
} input[3];
} inpt[3];
out block {
OutputVertex v;
} output;
noperspective out vec4 edgeDistance;
} outpt;
void emit(int index, vec4 position, vec3 normal, vec4 patchCoord)
{
output.v.position = position;
output.v.patchCoord = patchCoord;
output.v.normal = normal;
outpt.v.position = position;
outpt.v.patchCoord = patchCoord;
outpt.v.normal = normal;
gl_Position = ProjectionMatrix * output.v.position;
gl_Position = ProjectionMatrix * outpt.v.position;
EmitVertex();
}
@ -124,11 +125,11 @@ float edgeDistance(vec4 p, vec4 p0, vec4 p1)
void emit(int index, vec4 position, vec3 normal, vec4 patchCoord, vec4 edgeVerts[EDGE_VERTS])
{
output.v.edgeDistance[0] =
outpt.edgeDistance[0] =
edgeDistance(edgeVerts[index], edgeVerts[0], edgeVerts[1]);
output.v.edgeDistance[1] =
outpt.edgeDistance[1] =
edgeDistance(edgeVerts[index], edgeVerts[1], edgeVerts[2]);
output.v.edgeDistance[2] =
outpt.edgeDistance[2] =
edgeDistance(edgeVerts[index], edgeVerts[2], edgeVerts[0]);
emit(index, position, normal, patchCoord);
}
@ -144,29 +145,29 @@ void main()
vec3 normal[3];
// patch coords are computed in tessellation shader
patchCoord[0] = input[0].v.patchCoord;
patchCoord[1] = input[1].v.patchCoord;
patchCoord[2] = input[2].v.patchCoord;
patchCoord[0] = inpt[0].v.patchCoord;
patchCoord[1] = inpt[1].v.patchCoord;
patchCoord[2] = inpt[2].v.patchCoord;
#ifdef USE_PTEX_DISPLACEMENT
position[0] = displacement(input[0].v.position, input[0].v.normal, patchCoord[0]);
position[1] = displacement(input[1].v.position, input[1].v.normal, patchCoord[1]);
position[2] = displacement(input[2].v.position, input[2].v.normal, patchCoord[2]);
position[0] = displacement(inpt[0].v.position, inpt[0].v.normal, patchCoord[0]);
position[1] = displacement(inpt[1].v.position, inpt[1].v.normal, patchCoord[1]);
position[2] = displacement(inpt[2].v.position, inpt[2].v.normal, patchCoord[2]);
#else
position[0] = input[0].v.position;
position[1] = input[1].v.position;
position[2] = input[2].v.position;
position[0] = inpt[0].v.position;
position[1] = inpt[1].v.position;
position[2] = inpt[2].v.position;
#endif
normal[0] = input[0].v.normal;
normal[1] = input[1].v.normal;
normal[2] = input[2].v.normal;
normal[0] = inpt[0].v.normal;
normal[1] = inpt[1].v.normal;
normal[2] = inpt[2].v.normal;
#if defined(GEOMETRY_OUT_WIRE) || defined(GEOMETRY_OUT_LINE)
vec4 edgeVerts[EDGE_VERTS];
edgeVerts[0] = ProjectionMatrix * input[0].v.position;
edgeVerts[1] = ProjectionMatrix * input[1].v.position;
edgeVerts[2] = ProjectionMatrix * input[2].v.position;
edgeVerts[0] = ProjectionMatrix * inpt[0].v.position;
edgeVerts[1] = ProjectionMatrix * inpt[1].v.position;
edgeVerts[2] = ProjectionMatrix * inpt[2].v.position;
edgeVerts[0].xy /= edgeVerts[0].w;
edgeVerts[1].xy /= edgeVerts[1].w;
@ -193,7 +194,8 @@ void main()
in block {
OutputVertex v;
} input;
noperspective in vec4 edgeDistance;
} inpt;
out vec4 outColor;
@ -281,7 +283,7 @@ edgeColor(vec4 Cfill, vec4 edgeDistance)
{
#if defined(GEOMETRY_OUT_WIRE) || defined(GEOMETRY_OUT_LINE)
float d =
min(input.v.edgeDistance[0], min(input.v.edgeDistance[1], input.v.edgeDistance[2]));
min(inpt.edgeDistance[0], min(inpt.edgeDistance[1], inpt.edgeDistance[2]));
vec4 Cedge = vec4(0.5, 0.5, 0.5, 1.0);
float p = exp2(-2 * d * d);
@ -297,26 +299,26 @@ edgeColor(vec4 Cfill, vec4 edgeDistance)
void
main()
{
vec3 N = (gl_FrontFacing ? input.v.normal : -input.v.normal);
vec3 N = (gl_FrontFacing ? inpt.v.normal : -inpt.v.normal);
#ifdef USE_PTEX_DISPLACEMENT
N = perturbNormalFromDisplacement(input.v.position.xyz,
N = perturbNormalFromDisplacement(inpt.v.position.xyz,
N,
input.v.patchCoord);
inpt.v.patchCoord);
#endif
vec4 Cf = vec4(1.0);
#if defined(GEOMETRY_OUT_WIRE) || defined(GEOMETRY_OUT_LINE)
Cf = edgeColor(Cf, input.v.edgeDistance);
Cf = edgeColor(Cf, inpt.edgeDistance);
#endif
#ifdef USE_PTEX_COLOR
Cf = Cf * (vec4(1) - vec4(PTexLookup(input.v.patchCoord,
Cf = Cf * (vec4(1) - vec4(PTexLookup(inpt.v.patchCoord,
textureImage_Data,
textureImage_Packing,
textureImage_Pages).x));
#endif
Cf = lighting(Cf, input.v.position.xyz, N);
Cf = lighting(Cf, inpt.v.position.xyz, N);
outColor = Cf;
}

View File

@ -65,7 +65,7 @@ uniform float bumpScale = 1.0;
vec4 GeneratePatchCoord(vec2 localUV) // for non-adpative
{
ivec2 ptexIndex = texelFetchBuffer(g_ptexIndicesBuffer, gl_PrimitiveID).xy;
ivec2 ptexIndex = texelFetch(g_ptexIndicesBuffer, gl_PrimitiveID).xy;
int faceID = ptexIndex.x;
int lv = 1 << (ptexIndex.y & 0xf);
int u = (ptexIndex.y >> 17) & 0x3ff;
@ -94,11 +94,11 @@ vec4 PTexLookup(vec4 patchCoord,
#ifdef USE_PTEX_DISPLACEMENT
#define OSD_DISPLACEMENT_CALLBACK \
output.v.position = \
displacement(output.v.position, \
output.v.normal, \
output.v.patchCoord);
#define OSD_DISPLACEMENT_CALLBACK \
outpt.v.position = \
displacement(outpt.v.position, \
outpt.v.normal, \
outpt.v.patchCoord);
uniform sampler2DArray textureDisplace_Data;
uniform samplerBuffer textureDisplace_Packing;
@ -124,12 +124,12 @@ layout (location=1) in vec3 normal;
out block {
OutputVertex v;
} output;
} outpt;
void main()
{
output.v.position = ModelViewMatrix * position;
output.v.normal = (ModelViewMatrix * vec4(normal, 0)).xyz;
outpt.v.position = ModelViewMatrix * position;
outpt.v.normal = (ModelViewMatrix * vec4(normal, 0)).xyz;
}
#endif
@ -151,7 +151,7 @@ void main()
in block {
OutputVertex v;
} input[4];
} inpt[4];
#endif // PRIM_QUAD
@ -165,23 +165,24 @@ void main()
in block {
OutputVertex v;
} input[3];
} inpt[3];
#endif // PRIM_TRI
out block {
OutputVertex v;
} output;
noperspective out vec4 edgeDistance;
} outpt;
// --------------------------------------
void emit(vec4 position, vec3 normal, vec4 patchCoord)
{
output.v.position = position;
output.v.patchCoord = patchCoord;
output.v.normal = normal;
outpt.v.position = position;
outpt.v.patchCoord = patchCoord;
outpt.v.normal = normal;
gl_Position = ProjectionMatrix * output.v.position;
gl_Position = ProjectionMatrix * outpt.v.position;
EmitVertex();
}
@ -196,18 +197,18 @@ float edgeDistance(vec4 p, vec4 p0, vec4 p1)
void emit(int index, vec4 position, vec3 normal, vec4 patchCoord, vec4 edgeVerts[EDGE_VERTS])
{
output.v.edgeDistance[0] =
outpt.edgeDistance[0] =
edgeDistance(edgeVerts[index], edgeVerts[0], edgeVerts[1]);
output.v.edgeDistance[1] =
outpt.edgeDistance[1] =
edgeDistance(edgeVerts[index], edgeVerts[1], edgeVerts[2]);
#ifdef PRIM_TRI
output.v.edgeDistance[2] =
outpt.edgeDistance[2] =
edgeDistance(edgeVerts[index], edgeVerts[2], edgeVerts[0]);
#endif
#ifdef PRIM_QUAD
output.v.edgeDistance[2] =
outpt.edgeDistance[2] =
edgeDistance(edgeVerts[index], edgeVerts[2], edgeVerts[3]);
output.v.edgeDistance[3] =
outpt.edgeDistance[3] =
edgeDistance(edgeVerts[index], edgeVerts[3], edgeVerts[0]);
#endif
@ -232,15 +233,15 @@ void main()
patchCoord[3] = GeneratePatchCoord(vec2(0, 1));
#ifdef USE_PTEX_DISPLACEMENT
position[0] = displacement(input[0].v.position, input[0].v.normal, patchCoord[0]);
position[1] = displacement(input[1].v.position, input[1].v.normal, patchCoord[1]);
position[2] = displacement(input[2].v.position, input[2].v.normal, patchCoord[2]);
position[3] = displacement(input[3].v.position, input[3].v.normal, patchCoord[3]);
position[0] = displacement(inpt[0].v.position, inpt[0].v.normal, patchCoord[0]);
position[1] = displacement(inpt[1].v.position, inpt[1].v.normal, patchCoord[1]);
position[2] = displacement(inpt[2].v.position, inpt[2].v.normal, patchCoord[2]);
position[3] = displacement(inpt[3].v.position, inpt[3].v.normal, patchCoord[3]);
#else
position[0] = input[0].v.position;
position[1] = input[1].v.position;
position[2] = input[2].v.position;
position[3] = input[3].v.position;
position[0] = inpt[0].v.position;
position[1] = inpt[1].v.position;
position[2] = inpt[2].v.position;
position[3] = inpt[3].v.position;
#endif
#ifdef FLAT_NORMALS
@ -253,18 +254,18 @@ void main()
normal[2] = normal[0];
normal[3] = normal[0];
#else
normal[0] = input[0].v.normal;
normal[1] = input[1].v.normal;
normal[2] = input[2].v.normal;
normal[3] = input[3].v.normal;
normal[0] = inpt[0].v.normal;
normal[1] = inpt[1].v.normal;
normal[2] = inpt[2].v.normal;
normal[3] = inpt[3].v.normal;
#endif
#if defined(GEOMETRY_OUT_WIRE) || defined(GEOMETRY_OUT_LINE)
vec4 edgeVerts[EDGE_VERTS];
edgeVerts[0] = ProjectionMatrix * input[0].v.position;
edgeVerts[1] = ProjectionMatrix * input[1].v.position;
edgeVerts[2] = ProjectionMatrix * input[2].v.position;
edgeVerts[3] = ProjectionMatrix * input[3].v.position;
edgeVerts[0] = ProjectionMatrix * inpt[0].v.position;
edgeVerts[1] = ProjectionMatrix * inpt[1].v.position;
edgeVerts[2] = ProjectionMatrix * inpt[2].v.position;
edgeVerts[3] = ProjectionMatrix * inpt[3].v.position;
edgeVerts[0].xy /= edgeVerts[0].w;
edgeVerts[1].xy /= edgeVerts[1].w;
@ -289,18 +290,18 @@ void main()
vec3 normal[3];
// patch coords are computed in tessellation shader
patchCoord[0] = input[0].v.patchCoord;
patchCoord[1] = input[1].v.patchCoord;
patchCoord[2] = input[2].v.patchCoord;
patchCoord[0] = inpt[0].v.patchCoord;
patchCoord[1] = inpt[1].v.patchCoord;
patchCoord[2] = inpt[2].v.patchCoord;
#ifdef USE_PTEX_DISPLACEMENT
position[0] = displacement(input[0].v.position, input[0].v.normal, patchCoord[0]);
position[1] = displacement(input[1].v.position, input[1].v.normal, patchCoord[1]);
position[2] = displacement(input[2].v.position, input[2].v.normal, patchCoord[2]);
position[0] = displacement(inpt[0].v.position, inpt[0].v.normal, patchCoord[0]);
position[1] = displacement(inpt[1].v.position, inpt[1].v.normal, patchCoord[1]);
position[2] = displacement(inpt[2].v.position, inpt[2].v.normal, patchCoord[2]);
#else
position[0] = input[0].v.position;
position[1] = input[1].v.position;
position[2] = input[2].v.position;
position[0] = inpt[0].v.position;
position[1] = inpt[1].v.position;
position[2] = inpt[2].v.position;
#endif
#ifdef FLAT_NORMALS // emit flat normals for displaced surface
@ -310,16 +311,16 @@ void main()
normal[1] = normal[0];
normal[2] = normal[0];
#else
normal[0] = input[0].v.normal;
normal[1] = input[1].v.normal;
normal[2] = input[2].v.normal;
normal[0] = inpt[0].v.normal;
normal[1] = inpt[1].v.normal;
normal[2] = inpt[2].v.normal;
#endif
#if defined(GEOMETRY_OUT_WIRE) || defined(GEOMETRY_OUT_LINE)
vec4 edgeVerts[EDGE_VERTS];
edgeVerts[0] = ProjectionMatrix * input[0].v.position;
edgeVerts[1] = ProjectionMatrix * input[1].v.position;
edgeVerts[2] = ProjectionMatrix * input[2].v.position;
edgeVerts[0] = ProjectionMatrix * inpt[0].v.position;
edgeVerts[1] = ProjectionMatrix * inpt[1].v.position;
edgeVerts[2] = ProjectionMatrix * inpt[2].v.position;
edgeVerts[0].xy /= edgeVerts[0].w;
edgeVerts[1].xy /= edgeVerts[1].w;
@ -346,7 +347,8 @@ void main()
in block {
OutputVertex v;
} input;
noperspective in vec4 edgeDistance;
} inpt;
out vec4 outColor;
@ -449,7 +451,7 @@ lighting(vec4 texColor, vec3 Peye, vec3 Neye)
vec4 color = vec4(0);
#ifdef USE_PTEX_OCCLUSION
float occ = PTexLookup(input.v.patchCoord,
float occ = PTexLookup(inpt.v.patchCoord,
textureOcclusion_Data,
textureOcclusion_Packing,
textureOcclusion_Pages).x;
@ -487,12 +489,12 @@ edgeColor(vec4 Cfill, vec4 edgeDistance)
#if defined(GEOMETRY_OUT_WIRE) || defined(GEOMETRY_OUT_LINE)
#ifdef PRIM_TRI
float d =
min(input.v.edgeDistance[0], min(input.v.edgeDistance[1], input.v.edgeDistance[2]));
min(inpt.edgeDistance[0], min(inpt.edgeDistance[1], inpt.edgeDistance[2]));
#endif
#ifdef PRIM_QUAD
float d =
min(min(input.v.edgeDistance[0], input.v.edgeDistance[1]),
min(input.v.edgeDistance[2], input.v.edgeDistance[3]));
min(min(inpt.edgeDistance[0], inpt.edgeDistance[1]),
min(inpt.edgeDistance[2], inpt.edgeDistance[3]));
#endif
vec4 Cedge = vec4(1.0, 1.0, 0.0, 1.0);
float p = exp2(-2 * d * d);
@ -510,7 +512,7 @@ void
main()
{
#if USE_PTEX_COLOR
vec4 texColor = PTexLookup(input.v.patchCoord,
vec4 texColor = PTexLookup(inpt.v.patchCoord,
textureImage_Data,
textureImage_Packing,
textureImage_Pages);
@ -520,23 +522,23 @@ main()
#endif
#if USE_PTEX_NORMAL
vec3 normal = perturbNormalFromDisplacement(input.v.position.xyz,
input.v.normal,
input.v.patchCoord);
vec3 normal = perturbNormalFromDisplacement(inpt.v.position.xyz,
inpt.v.normal,
inpt.v.patchCoord);
#else
vec3 normal = input.v.normal;
vec3 normal = inpt.v.normal;
#endif
if (overrideColorEnable) {
texColor = overrideColor;
vec4 Cf = lighting(texColor, input.v.position.xyz, normal);
outColor = edgeColor(Cf, input.v.edgeDistance);
vec4 Cf = lighting(texColor, inpt.v.position.xyz, normal);
outColor = edgeColor(Cf, inpt.edgeDistance);
return;
}
#if USE_IBL
#ifdef USE_PTEX_OCCLUSION
float occ = PTexLookup(input.v.patchCoord,
float occ = PTexLookup(inpt.v.patchCoord,
textureOcclusion_Data,
textureOcclusion_Packing,
textureOcclusion_Pages).x;
@ -545,7 +547,7 @@ main()
#endif
#ifdef USE_PTEX_SPECULAR
float specular = PTexLookup(input.v.patchCoord,
float specular = PTexLookup(inpt.v.patchCoord,
textureSpecular_Data,
textureSpecular_Packing,
textureSpecular_Pages).x;
@ -555,7 +557,7 @@ main()
vec4 a = vec4(0, 0, 0, 1); //ambientColor;
vec4 d = getEnvironmentHDR(diffuseEnvironmentMap, normal) * 1.4;
vec3 eye = normalize(input.v.position.xyz - vec3(0,0,0));
vec3 eye = normalize(inpt.v.position.xyz - vec3(0,0,0));
vec3 reflect = reflect(eye, normal);
vec4 s = getEnvironmentHDR(specularEnvironmentMap, reflect);
const float fresnelBias = 0;
@ -569,10 +571,10 @@ main()
vec4 Cf = (a + d) * texColor + s * 0.5;
#else
vec4 Cf = lighting(texColor, input.v.position.xyz, normal);
vec4 Cf = lighting(texColor, inpt.v.position.xyz, normal);
#endif
outColor = edgeColor(Cf, input.v.edgeDistance);
outColor = edgeColor(Cf, inpt.edgeDistance);
}
#endif

View File

@ -86,11 +86,11 @@ vec4 PTexLookup(vec4 patchCoord,
#ifdef USE_PTEX_DISPLACEMENT
#define OSD_DISPLACEMENT_CALLBACK \
output.v.position = \
displacement(output.v.position, \
output.v.normal, \
output.v.patchCoord);
#define OSD_DISPLACEMENT_CALLBACK \
outpt.v.position = \
displacement(outpt.v.position, \
outpt.v.normal, \
outpt.v.patchCoord);
uniform sampler2DArray textureDisplace_Data;
uniform samplerBuffer textureDisplace_Packing;

View File

@ -69,6 +69,7 @@ set(PUBLIC_HEADER_FILES
mesh.h
multiMeshFactory.h
patchParam.h
patchMap.h
patchTables.h
patchTablesFactory.h
subdivisionTables.h

View File

@ -375,9 +375,10 @@ FarMultiMeshFactory<T, U>::spliceSubdivisionTables(FarMesh<U> *farMesh, FarMeshV
// merge batch, model by model
FarKernelBatchVector &batches = farMesh->_batches;
int editTableIndexOffset = 0;
for (size_t i = 0; i < meshes.size(); ++i) {
for (int i = 0; i < (int)meshes.size(); ++i) {
for (int j = 0; j < (int)meshes[i]->_batches.size(); ++j) {
FarKernelBatch batch = meshes[i]->_batches[j];
batch._meshIndex = i;
batch._vertexOffset += vertexOffsets[i];
if (batch._kernelType == FarKernelBatch::CATMARK_FACE_VERTEX or

366
opensubdiv/far/patchMap.h Normal file
View File

@ -0,0 +1,366 @@
//
// Copyright (C) Pixar. All rights reserved.
//
// This license governs use of the accompanying software. If you
// use the software, you accept this license. If you do not accept
// the license, do not use the software.
//
// 1. Definitions
// The terms "reproduce," "reproduction," "derivative works," and
// "distribution" have the same meaning here as under U.S.
// copyright law. A "contribution" is the original software, or
// any additions or changes to the software.
// A "contributor" is any person or entity that distributes its
// contribution under this license.
// "Licensed patents" are a contributor's patent claims that read
// directly on its contribution.
//
// 2. Grant of Rights
// (A) Copyright Grant- Subject to the terms of this license,
// including the license conditions and limitations in section 3,
// each contributor grants you a non-exclusive, worldwide,
// royalty-free copyright license to reproduce its contribution,
// prepare derivative works of its contribution, and distribute
// its contribution or any derivative works that you create.
// (B) Patent Grant- Subject to the terms of this license,
// including the license conditions and limitations in section 3,
// each contributor grants you a non-exclusive, worldwide,
// royalty-free license under its licensed patents to make, have
// made, use, sell, offer for sale, import, and/or otherwise
// dispose of its contribution in the software or derivative works
// of the contribution in the software.
//
// 3. Conditions and Limitations
// (A) No Trademark License- This license does not grant you
// rights to use any contributor's name, logo, or trademarks.
// (B) If you bring a patent claim against any contributor over
// patents that you claim are infringed by the software, your
// patent license from such contributor to the software ends
// automatically.
// (C) If you distribute any portion of the software, you must
// retain all copyright, patent, trademark, and attribution
// notices that are present in the software.
// (D) If you distribute any portion of the software in source
// code form, you may do so only under this license by including a
// complete copy of this license with your distribution. If you
// distribute any portion of the software in compiled or object
// code form, you may only do so under a license that complies
// with this license.
// (E) The software is licensed "as-is." You bear the risk of
// using it. The contributors give no express warranties,
// guarantees or conditions. You may have additional consumer
// rights under your local laws which this license cannot change.
// To the extent permitted under your local laws, the contributors
// exclude the implied warranties of merchantability, fitness for
// a particular purpose and non-infringement.
//
#ifndef FAR_PATCH_MAP_H
#define FAR_PATCH_MAP_H
#include "../version.h"
#include "../far/patchTables.h"
#include <cassert>
namespace OpenSubdiv {
namespace OPENSUBDIV_VERSION {
/// \brief An quadtree-based map connecting coarse faces to their sub-patches
///
/// FarPatchTables::PatchArrays contain lists of patches that represent the limit
/// surface of a mesh, sorted by their topological type. These arrays break the
/// connection between coarse faces and their sub-patches.
///
/// The PatchMap provides a quad-tree based lookup structure that, given a singular
/// parametric location, can efficiently return a handle to the sub-patch that
/// contains this location.
///
class FarPatchMap {
public:
/// Handle that can be used as unique patch identifier within FarPatchTables
struct Handle {
unsigned int patchArrayIdx, // OsdPatchArray containing the patch
patchIdx, // Absolute index of the patch
vertexOffset; // Offset to the first CV of the patch
};
/// Constructor
///
/// @param patchTables A valid set of FarPatchTables
///
FarPatchMap( FarPatchTables const & patchTables );
/// Returns a handle to the sub-patch of the face at the given (u,v).
/// Note : the faceid corresponds to quadrangulated face indices (ie. quads
/// count as 1 index, non-quads add as many indices as they have vertices)
///
/// @param faceid The index of the face
///
/// @param u Local u parameter
///
/// @param v Local v parameter
///
/// @return A patch handle or NULL if the face does not exist or the
/// limit surface is tagged as a hole at the given location
///
Handle const * FindPatch( int faceid, float u, float v ) const;
private:
void initialize( FarPatchTables const & patchTables );
// Quadtree node with 4 children
struct QuadNode {
struct Child {
unsigned int isSet:1, // true if the child has been set
isLeaf:1, // true if the child is a QuadNode
idx:30; // child index (either QuadNode or Handle)
};
// sets all the children to point to the patch of index patchIdx
void SetChild(int patchIdx);
// sets the child in "quadrant" to point to the node or patch of the given index
void SetChild(unsigned char quadrant, int child, bool isLeaf=true);
Child children[4];
};
typedef std::vector<QuadNode> QuadTree;
// adds a child to a parent node and pushes it back on the tree
static QuadNode * addChild( QuadTree & quadtree, QuadNode * parent, int quadrant );
// given a median, transforms the (u,v) to the quadrant they point to, and
// return the quadrant index.
//
// Quadrants indexing:
//
// (0,0) o-----o-----o
// | | |
// | 0 | 3 |
// | | |
// o-----o-----o
// | | |
// | 1 | 2 |
// | | |
// o-----o-----o (1,1)
//
template <class T> static int resolveQuadrant(T & median, T & u, T & v);
std::vector<Handle> _handles; // all the patches in the FarPatchTable
std::vector<QuadNode> _quadtree; // quadtree nodes
};
// Constructor
inline
FarPatchMap::FarPatchMap( FarPatchTables const & patchTables ) {
initialize( patchTables );
}
// sets all the children to point to the patch of index patchIdx
inline void
FarPatchMap::QuadNode::SetChild(int patchIdx) {
for (int i=0; i<4; ++i) {
children[i].isSet=true;
children[i].isLeaf=true;
children[i].idx=patchIdx;
}
}
// sets the child in "quadrant" to point to the node or patch of the given index
inline void
FarPatchMap::QuadNode::SetChild(unsigned char quadrant, int idx, bool isLeaf) {
assert(quadrant<4);
children[quadrant].isSet = true;
children[quadrant].isLeaf = isLeaf;
children[quadrant].idx = idx;
}
// adds a child to a parent node and pushes it back on the tree
inline FarPatchMap::QuadNode *
FarPatchMap::addChild( QuadTree & quadtree, QuadNode * parent, int quadrant ) {
quadtree.push_back(QuadNode());
int idx = (int)quadtree.size()-1;
parent->SetChild(quadrant, idx, false);
return &(quadtree[idx]);
}
// given a median, transforms the (u,v) to the quadrant they point to, and
// return the quadrant index.
template <class T> int
FarPatchMap::resolveQuadrant(T & median, T & u, T & v) {
int quadrant = -1;
if (u<median) {
if (v<median) {
quadrant = 0;
} else {
quadrant = 1;
v-=median;
}
} else {
if (v<median) {
quadrant = 3;
} else {
quadrant = 2;
v-=median;
}
u-=median;
}
return quadrant;
}
/// Returns a handle to the sub-patch of the face at the given (u,v).
inline FarPatchMap::Handle const *
FarPatchMap::FindPatch( int faceid, float u, float v ) const {
if (faceid>(int)_quadtree.size())
return NULL;
assert( (u>=0.0f) and (u<=1.0f) and (v>=0.0f) and (v<=1.0f) );
QuadNode const * node = &_quadtree[faceid];
float half = 0.5f;
// 0xFF : we should never have depths greater than k_InfinitelySharp
for (int depth=0; depth<0xFF; ++depth) {
float delta = half * 0.5f;
int quadrant = resolveQuadrant( half, u, v );
assert(quadrant>=0);
// is the quadrant a hole ?
if (not node->children[quadrant].isSet)
return 0;
if (node->children[quadrant].isLeaf) {
return &_handles[node->children[quadrant].idx];
} else {
node = &_quadtree[node->children[quadrant].idx];
}
half = delta;
}
assert(0);
return 0;
}
// Constructor
inline void
FarPatchMap::initialize( FarPatchTables const & patchTables ) {
int nfaces = 0, npatches = (int)patchTables.GetNumPatches();
if (not npatches)
return;
FarPatchTables::PatchArrayVector const & patchArrays =
patchTables.GetPatchArrayVector();
FarPatchTables::PatchParamTable const & paramTable =
patchTables.GetPatchParamTable();
// populate subpatch handles vector
_handles.resize(npatches);
for (int arrayIdx=0, current=0; arrayIdx<(int)patchArrays.size(); ++arrayIdx) {
FarPatchTables::PatchArray const & parray = patchArrays[arrayIdx];
int ringsize = parray.GetDescriptor().GetNumControlVertices();
for (unsigned int j=0; j < parray.GetNumPatches(); ++j) {
FarPatchParam const & param = paramTable[parray.GetPatchIndex()+j];
Handle & h = _handles[current];
h.patchArrayIdx = arrayIdx;
h.patchIdx = (unsigned int)current;
h.vertexOffset = j * ringsize;
nfaces = std::max(nfaces, (int)param.faceIndex);
++current;
}
}
++nfaces;
// temporary vector to hold the quadtree while under construction
std::vector<QuadNode> quadtree;
// reserve memory for the octree nodes (size is a worse-case approximation)
quadtree.reserve( nfaces + npatches );
// each coarse face has a root node associated to it that we need to initialize
quadtree.resize(nfaces);
// populate the quadtree from the FarPatchArrays sub-patches
for (int i=0, handleIdx=0; i<(int)patchArrays.size(); ++i) {
FarPatchTables::PatchArray const & parray = patchArrays[i];
for (unsigned int j=0; j < parray.GetNumPatches(); ++j, ++handleIdx) {
FarPatchParam const & param = paramTable[parray.GetPatchIndex()+j];
FarPatchParam::BitField bits = param.bitField;
unsigned char depth = bits.GetDepth();
QuadNode * node = &quadtree[ param.faceIndex ];
if (depth==0) {
// special case : regular BSpline face w/ no sub-patches
node->SetChild( handleIdx );
continue;
}
short u = bits.GetU(),
v = bits.GetV(),
pdepth = bits.NonQuadRoot() ? depth-2 : depth-1,
half = 1 << pdepth;
for (unsigned char k=0; k<depth; ++k) {
short delta = half >> 1;
int quadrant = resolveQuadrant(half, u, v);
assert(quadrant>=0);
half = delta;
if (k==pdepth) {
// we have reached the depth of the sub-patch : add a leaf
assert( not node->children[quadrant].isSet );
node->SetChild(quadrant, handleIdx, true);
break;
} else {
// travel down the child node of the corresponding quadrant
if (not node->children[quadrant].isSet) {
// create a new branch in the quadrant
node = addChild(quadtree, node, quadrant);
} else {
// travel down an existing branch
node = &(quadtree[ node->children[quadrant].idx ]);
}
}
}
}
}
// copy the resulting quadtree to eliminate un-unused vector capacity
_quadtree = quadtree;
}
} // end namespace OPENSUBDIV_VERSION
using namespace OPENSUBDIV_VERSION;
} // end namespace OpenSubdiv
#endif /* FAR_PATCH_PARAM */

View File

@ -58,6 +58,10 @@
#ifndef FAR_PATCH_PARAM_H
#define FAR_PATCH_PARAM_H
#include "../version.h"
#include <cassert>
namespace OpenSubdiv {
namespace OPENSUBDIV_VERSION {
@ -117,10 +121,31 @@ struct FarPatchParam {
/// True if the parent coarse face is a non-quad
bool NonQuadRoot() const { return (field >> 4) & 0x1; }
/// Returns the fratcion of normalized parametric space covered by the
/// sub-patch.
float GetParamFraction() const;
/// Returns the level of subdivision of the patch
unsigned char GetDepth() const { return (field & 0xf); }
/// The (u,v) pair is normalized to this sub-parametric space.
///
/// @param u u parameter
///
/// @param v v parameter
///
void Normalize( float & u, float & v ) const;
/// Rotate (u,v) pair to compensate for transition pattern and boundary
/// orientations.
///
/// @param u u parameter
///
/// @param v v parameter
///
void Rotate( float & u, float & v ) const;
/// Resets the values to 0
void Clear() { field = 0; }
@ -146,9 +171,44 @@ struct FarPatchParam {
void Clear() {
faceIndex = 0;
bitField.Clear();
}
}
};
inline float
FarPatchParam::BitField::GetParamFraction( ) const {
if (NonQuadRoot()) {
return 1.0f / float( 1 << (GetDepth()-1) );
} else {
return 1.0f / float( 1 << GetDepth() );
}
}
inline void
FarPatchParam::BitField::Normalize( float & u, float & v ) const {
float frac = GetParamFraction();
// top left corner
float pu = (float)GetU()*frac;
float pv = (float)GetV()*frac;
// normalize u,v coordinates
u = (u - pu) / frac,
v = (v - pv) / frac;
}
inline void
FarPatchParam::BitField::Rotate( float & u, float & v ) const {
switch( GetRotation() ) {
case 0 : break;
case 1 : { float tmp=v; v=1.0f-u; u=tmp; } break;
case 2 : { u=1.0f-u; v=1.0f-v; } break;
case 3 : { float tmp=u; u=1.0f-v; v=tmp; } break;
default:
assert(0);
}
}
} // end namespace OPENSUBDIV_VERSION
using namespace OPENSUBDIV_VERSION;

View File

@ -64,6 +64,7 @@
#include <cstdlib>
#include <cassert>
#include <algorithm>
#include <vector>
#include <map>
@ -337,49 +338,6 @@ public:
typedef std::vector<PatchArray> PatchArrayVector;
/// Unique patch identifier within a PatchArrayVector
struct PatchHandle {
unsigned int array, // OsdPatchArray containing the patch
vertexOffset, // Offset to the first CV of the patch
serialIndex; // Serialized Index of the patch
};
/// \brief Maps sub-patches to coarse faces
class PatchMap {
public:
// Constructor
PatchMap( FarPatchTables const & patchTables );
/// \brief Returns the number and list of patch indices for a given face.
///
/// PatchMaps map coarse faces to their childrn feature adaptive patches.
/// Coarse faces are indexed using their ptex face ID to resolve parametric
/// ambiguity on non-quad faces. Note : this "map" is actually a vector, so
/// queries are O(1) order.
///
/// @param faceid the face index to search for
///
/// @param npatches the number of children patches found for the faceid
///
/// @param patches a set of pointers to the individual patch handles
///
bool GetChildPatchesHandles( int faceid, int * npatches, PatchHandle const ** patches ) const;
private:
typedef std::multimap<unsigned int, PatchHandle> MultiMap;
// Patch handle allowing location of individual patch data inside patch
// arrays or in serialized form
std::vector<PatchHandle> _handles;
// offset to the first handle of the child patches for each coarse face
std::vector<unsigned int> _offsets;
};
/// Constructor
///
/// @param patchArrays Vector of descriptors and ranges for arrays of patches
@ -531,7 +489,23 @@ FarPatchTables::FarPatchTables(PatchArrayVector const & patchArrays,
inline bool
FarPatchTables::IsFeatureAdaptive() const {
return ((not _vertexValenceTable.empty()) and (not _quadOffsetTable.empty()));
// the vertex valence table is only used by Gregory patches, so the PatchTables
// contain feature adaptive patches if this is not empty.
if (not _vertexValenceTable.empty())
return true;
PatchArrayVector const & parrays = GetPatchArrayVector();
// otherwise, we have to check each patch array
for (int i=0; i<(int)parrays.size(); ++i) {
if (parrays[i].GetDescriptor().GetType() >= REGULAR and
parrays[i].GetDescriptor().GetType() <= GREGORY_BOUNDARY)
return true;
}
return false;
}
// Returns the number of control vertices expected for a patch of this type
@ -596,84 +570,6 @@ FarPatchTables::Descriptor::operator ++ () {
return *this;
}
// Constructor
inline
FarPatchTables::PatchMap::PatchMap( FarPatchTables const & patchTables ) {
// Create a PatchHandle for each patch in the primitive
int npatches = (int)patchTables.GetNumPatches();
_handles.reserve(npatches);
FarPatchTables::PatchArrayVector const & patchArrays =
patchTables.GetPatchArrayVector();
FarPatchTables::PatchParamTable const & paramTable =
patchTables.GetPatchParamTable();
assert( not paramTable.empty() );
int nfaces =0;
MultiMap mmap;
for (int arrayid = 0; arrayid < (int)patchArrays.size(); ++arrayid) {
FarPatchTables::PatchArray const & pa = patchArrays[arrayid];
int ringsize = pa.GetDescriptor().GetNumControlVertices();
for (unsigned int j=0; j < pa.GetNumPatches(); ++j) {
int faceId = paramTable[pa.GetPatchIndex()+j].faceIndex;
PatchHandle handle = { arrayid, j*ringsize, (unsigned int)mmap.size() };
mmap.insert( std::pair<unsigned int, PatchHandle>(faceId, handle));
nfaces = std::max(nfaces, faceId);
}
}
++nfaces;
_handles.resize( mmap.size() );
_offsets.reserve( nfaces );
_offsets.push_back(0);
// Serialize the multi-map
unsigned int handlesIdx = 0, faceId=mmap.begin()->first;
for (MultiMap::const_iterator it=mmap.begin(); it!=mmap.end(); ++it, ++handlesIdx) {
assert(it->first >= faceId);
if (it->first != faceId) {
faceId = it->first;
// position the offset marker to the new face
_offsets.push_back( handlesIdx );
}
// copy the patch id into the table
_handles[handlesIdx] = it->second;
}
}
// Returns the number and list of patch indices for a given face.
inline bool
FarPatchTables::PatchMap::GetChildPatchesHandles( int faceid, int * npatches, PatchHandle const ** patches ) const {
if (_handles.empty() or _offsets.empty() or (faceid>=(int)_offsets.size()))
return false;
*npatches = (faceid==(int)_offsets.size()-1 ?
(unsigned int)_handles.size()-1 : _offsets[faceid+1]) - _offsets[faceid] + 1;
*patches = &_handles[ _offsets[faceid] ];
return true;
}
// Returns a pointer to the vertex indices of uniformly subdivided faces
inline unsigned int const *
FarPatchTables::GetFaceVertices(int level) const {
@ -736,13 +632,8 @@ FarPatchTables::findPatchArray( FarPatchTables::Descriptor desc ) {
// Returns the total number of patches stored in the tables
inline int
FarPatchTables::GetNumPatches() const {
int result=0;
for (int i=0; i<(int)_patchArrays.size(); ++i) {
result += _patchArrays[i].GetNumPatches();
}
return result;
// there is one PatchParam record for each patch in the mesh
return (int)GetPatchParamTable().size();
}
// Returns the total number of control vertex indices in the tables

View File

@ -156,6 +156,9 @@ private:
// The number of patch arrays in the mesh
int getNumPatchArrays() const;
// The number of patches in the mesh
static int getNumPatches( FarPatchTables::PatchArrayVector const & parrays );
// Reserves tables based on the contents of the PatchArrayVector
static void allocateTables( FarPatchTables * tables, int fvarwidth );
@ -254,7 +257,7 @@ template <class T> void
FarPatchTablesFactory<T>::allocateTables( FarPatchTables * tables, int fvarwidth ) {
int nverts = tables->GetNumControlVertices(),
npatches = tables->GetNumPatches();
npatches = getNumPatches(tables->GetPatchArrayVector());
if (nverts==0 or npatches==0)
return;
@ -637,6 +640,17 @@ FarPatchTablesFactory<T>::getNumPatchArrays() const {
return result;
}
template <class T> int
FarPatchTablesFactory<T>::getNumPatches( FarPatchTables::PatchArrayVector const & parrays ) {
int result=0;
for (int i=0; i<(int)parrays.size(); ++i) {
result += parrays[i].GetNumPatches();
}
return result;
}
template <class T> void
FarPatchTablesFactory<T>::pushPatchArray( FarPatchTables::Descriptor desc,
FarPatchTables::PatchArrayVector & parray,
@ -705,7 +719,8 @@ FarPatchTablesFactory<T>::Create( int maxlevel, int maxvalence, bool requireFVar
iptrs[(int)pa->GetDescriptor().GetPattern()].getValue( *it ) = &result->_patches[pa->GetVertIndex()];
pptrs[(int)pa->GetDescriptor().GetPattern()].getValue( *it ) = &result->_paramTable[pa->GetPatchIndex()];
if (requireFVarData)
if (fvarwidth>0)
fptrs[(int)pa->GetDescriptor().GetPattern()].getValue( *it ) = &result->_fvarTable[pa->GetPatchIndex() * 4 * fvarwidth];
}

View File

@ -115,6 +115,7 @@ set(PUBLIC_HEADER_FILES
evalLimitContext.h
mesh.h
nonCopyable.h
opengl.h
drawContext.h
drawRegistry.h
vertex.h

View File

@ -57,14 +57,10 @@
// a particular purpose and non-infringement.
//
#if defined(__APPLE__)
#include <OpenGL/gl3.h>
#else
#include <GL/glew.h>
#endif
#include "../osd/clGLVertexBuffer.h"
#include "../osd/opengl.h"
#include <cassert>
namespace OpenSubdiv {

View File

@ -59,6 +59,8 @@
#include "../version.h"
#include "../osd/opengl.h"
#if defined(__APPLE__)
#include <OpenCL/opencl.h>
#else

View File

@ -67,7 +67,7 @@ namespace OpenSubdiv {
namespace OPENSUBDIV_VERSION {
OsdCpuEvalLimitContext *
OsdCpuEvalLimitContext::Create(FarMesh<OsdVertex> const * farmesh) {
OsdCpuEvalLimitContext::Create(FarMesh<OsdVertex> const * farmesh, bool requireFVarData) {
assert(farmesh);
@ -75,10 +75,10 @@ OsdCpuEvalLimitContext::Create(FarMesh<OsdVertex> const * farmesh) {
if (not farmesh->GetPatchTables())
return NULL;
return new OsdCpuEvalLimitContext(farmesh);
return new OsdCpuEvalLimitContext(farmesh, requireFVarData);
}
OsdCpuEvalLimitContext::OsdCpuEvalLimitContext(FarMesh<OsdVertex> const * farmesh) :
OsdCpuEvalLimitContext::OsdCpuEvalLimitContext(FarMesh<OsdVertex> const * farmesh, bool requireFVarData) :
OsdEvalLimitContext(farmesh) {
FarPatchTables const * patchTables = farmesh->GetPatchTables();
@ -89,9 +89,9 @@ OsdCpuEvalLimitContext::OsdCpuEvalLimitContext(FarMesh<OsdVertex> const * farmes
_patchArrays = patchTables->GetPatchArrayVector();
_vertexValenceBuffer = patchTables->GetVertexValenceTable();
_vertexValenceTable = patchTables->GetVertexValenceTable();
_quadOffsetBuffer = patchTables->GetQuadOffsetTable();
_quadOffsetTable = patchTables->GetQuadOffsetTable();
_maxValence = patchTables->GetMaxValence();
@ -117,13 +117,51 @@ OsdCpuEvalLimitContext::OsdCpuEvalLimitContext(FarMesh<OsdVertex> const * farmes
}
}
_patchMap = new FarPatchTables::PatchMap( *patchTables );
// Copy the face-varying table if necessary
if (requireFVarData) {
_fvarwidth = farmesh->GetTotalFVarWidth();
if (_fvarwidth>0) {
_fvarData = patchTables->GetFVarDataTable();
}
}
_patchMap = new FarPatchMap( *patchTables );
}
OsdCpuEvalLimitContext::~OsdCpuEvalLimitContext() {
delete _patchMap;
}
void
OsdCpuEvalLimitContext::VertexData::Unbind() {
inDesc.Reset();
in.Unbind();
outDesc.Reset();
out.Unbind();
outDu.Unbind();
outDv.Unbind();
}
void
OsdCpuEvalLimitContext::VaryingData::Unbind() {
inDesc.Reset();
in.Unbind();
outDesc.Reset();
out.Unbind();
}
void
OsdCpuEvalLimitContext::FaceVaryingData::Unbind() {
inDesc.Reset();
outDesc.Reset();
out.Unbind();
}
} // end namespace OPENSUBDIV_VERSION
} // end namespace OpenSubdiv

View File

@ -62,6 +62,7 @@
#include "../osd/evalLimitContext.h"
#include "../osd/vertexDescriptor.h"
#include "../far/patchTables.h"
#include "../far/patchMap.h"
#include <map>
#include <stdio.h>
@ -71,82 +72,235 @@ namespace OPENSUBDIV_VERSION {
class OsdCpuEvalLimitContext : public OsdEvalLimitContext {
public:
/// \brief Factory
/// Returns an EvalLimitContext from the given farmesh.
/// Note : the farmesh is expected to be feature-adaptive and have ptex
/// coordinates tables.
static OsdCpuEvalLimitContext * Create(FarMesh<OsdVertex> const * farmesh);
///
/// @param farmesh a pointer to an initialized farmesh
///
/// @param requireFVarData flag for generating face-varying data
///
static OsdCpuEvalLimitContext * Create(FarMesh<OsdVertex> const * farmesh,
bool requireFVarData=false);
/// Destructor
virtual ~OsdCpuEvalLimitContext();
/// Binds the data buffers.
///
/// @param inDesc vertex buffer data descriptor shared by all input data buffers
///
/// @param inQ input vertex data
///
/// @param outDesc vertex buffer data descriptor shared by all output data buffers
///
/// @param outQ output vertex data
///
/// @param outdQu optional output derivative along "u" of the vertex data
///
/// @param outdQv optional output derivative along "v" of the vertex data
///
template<class VERTEX_BUFFER, class OUTPUT_BUFFER>
void BindVertexBuffers( OsdVertexBufferDescriptor const & inDesc, VERTEX_BUFFER *inQ,
OsdVertexBufferDescriptor const & outDesc, OUTPUT_BUFFER *outQ,
OUTPUT_BUFFER *outdQu=0,
OUTPUT_BUFFER *outdQv=0) {
_inDesc = inDesc;
_inQ = inQ ? inQ->BindCpuBuffer() : 0;
_outDesc = outDesc;
_outQ = outQ ? outQ->BindCpuBuffer() : 0 ;
_outdQu = outdQu ? outdQu->BindCpuBuffer() : 0 ;
_outdQv = outdQv ? outdQv->BindCpuBuffer() : 0 ;
}
/// Unbind the data buffers
void UnbindVertexBuffers() {
_inQ = 0;
_outQ = 0;
_outdQu = 0;
_outdQv = 0;
}
/// A container able to bind vertex buffer data as input or output streams.
class DataStream {
public:
/// Constructor
DataStream() : _data(0) { }
/// Returns the input vertex buffer descriptor
const OsdVertexBufferDescriptor & GetInputDesc() const {
return _inDesc;
}
/// Binds the stream to the context (and moves the data to the appropriate
/// compute device)
///
/// @param data a valid OsdVertexBuffer
///
template <class BUFFER> void Bind( BUFFER * data ) {
_data = data ? data->BindCpuBuffer() : 0;
}
/// Returns the output vertex buffer descriptor
const OsdVertexBufferDescriptor & GetOutputDesc() const {
return _outDesc;
}
/// True if the stream has been bound
bool IsBound() const {
return (_data!=NULL);
}
/// Returns the input vertex buffer data
float const * GetInputVertexData() const {
return _inQ;
}
/// Unbinds the stream
void Unbind() {
_data=0;
}
/// Returns the output vertex buffer data
float * GetOutputVertexData() const {
return _outQ;
}
protected:
float * _data;
};
/// Returns the U derivative of the output vertex buffer data
float * GetOutputVertexDataUDerivative() const {
return _outdQu;
}
/// \brief Input (const) data stream
class InputDataStream : public DataStream {
public:
/// Const accessor
float const * GetData() const {
return _data;
}
};
/// Returns the V derivative of the output vertex buffer data
float * GetOutputVertexDataVDerivative() const {
return _outdQv;
}
/// \brief Output (const) data stream
class OutputDataStream : public DataStream {
public:
/// Non-cont accessor
float * GetData() {
return _data;
}
};
/// Vertex-interpolated streams
struct VertexData {
/// input vertex-interpolated data descriptor
OsdVertexBufferDescriptor inDesc;
/// input vertex-interpolated data stream
InputDataStream in;
/// output vertex-interpolated data descriptor
OsdVertexBufferDescriptor outDesc;
/// output vertex-interpolated data stream and parametric derivative streams
OutputDataStream out,
outDu,
outDv;
/// Binds the vertex-interpolated data streams
///
/// @param iDesc data descriptor shared by all input data buffers
///
/// @param inQ input vertex data
///
/// @param oDesc data descriptor shared by all output data buffers
///
/// @param outQ output vertex data
///
/// @param outdQu output derivative along "u" of the vertex data (optional)
///
/// @param outdQv output derivative along "v" of the vertex data (optional)
///
template<class VERTEX_BUFFER, class OUTPUT_BUFFER>
void Bind( OsdVertexBufferDescriptor const & iDesc, VERTEX_BUFFER *inQ,
OsdVertexBufferDescriptor const & oDesc, OUTPUT_BUFFER *outQ,
OUTPUT_BUFFER *outdQu=0,
OUTPUT_BUFFER *outdQv=0) {
inDesc = iDesc;
in.Bind( inQ );
outDesc = oDesc;
out.Bind( outQ );
outDu.Bind( outdQu );
outDv.Bind( outdQv );
}
/// True if both the mandatory input and output streams have been bound
bool IsBound() const {
return in.IsBound() and out.IsBound();
}
/// Unbind the vertex data streams
void Unbind();
};
/// Returns an Eval data descriptor of the vertex-interpolated data currently
/// bound to this EvalLimitContext.
VertexData & GetVertexData() {
return _vertexData;
}
/// Varying-interpolated streams
struct VaryingData {
/// input varying-interpolated data descriptor
OsdVertexBufferDescriptor inDesc;
/// input varying-interpolated data stream
InputDataStream in;
/// output varying-interpolated data descriptor
OsdVertexBufferDescriptor outDesc;
/// output varying-interpolated data stream
OutputDataStream out;
/// Binds the varying-interpolated data streams
///
/// @param iDesc data descriptor shared by all input data buffers
///
/// @param inQ input varying data
///
/// @param oDesc data descriptor shared by all output data buffers
///
/// @param outQ output varying data
///
template<class VARYING_BUFFER, class OUTPUT_BUFFER>
void Bind( OsdVertexBufferDescriptor const & iDesc, VARYING_BUFFER *inQ,
OsdVertexBufferDescriptor const & oDesc, OUTPUT_BUFFER *outQ ) {
inDesc = iDesc;
in.Bind( inQ );
outDesc = oDesc;
out.Bind( outQ );
}
/// True if both the mandatory input and output streams have been bound
bool IsBound() const {
return in.IsBound() and out.IsBound();
}
/// Unbind the vertex data streams
void Unbind();
};
/// Returns an Eval data descriptor of the varying-interpolated data currently
/// bound to this EvalLimitContext.
VaryingData & GetVaryingData() {
return _varyingData;
}
/// Face-Varying-interpolated streams
struct FaceVaryingData {
/// input face-varying-interpolated data descriptor
OsdVertexBufferDescriptor inDesc;
/// output face-varying-interpolated data descriptor
OsdVertexBufferDescriptor outDesc;
/// output face-varying-interpolated data stream and parametric derivative streams
OutputDataStream out;
/// Binds the face-varying-interpolated data streams
///
/// Note : currently we only support bilinear boundary interpolation rules
/// for face-varying data. Although Hbr supports 3 addition smooth rule sets,
/// the feature-adaptive patch interpolation code currently does not support
/// them, and neither does this EvalContext
///
/// @param iDesc data descriptor shared by all input data buffers
///
/// @param oDesc data descriptor shared by all output data buffers
///
/// @param outQ output face-varying data
///
template<class OUTPUT_BUFFER>
void Bind( OsdVertexBufferDescriptor const & iDesc,
OsdVertexBufferDescriptor const & oDesc, OUTPUT_BUFFER *outQ ) {
inDesc = iDesc;
outDesc = oDesc;
out.Bind( outQ );
}
/// True if the output stream has been bound
bool IsBound() const {
return out.IsBound();
}
/// Unbind the vertex data streams
void Unbind();
};
/// Returns an Eval data descriptor of the face-varying-interpolated data
/// currently bound to this EvalLimitContext.
FaceVaryingData & GetFaceVaryingData() {
return _faceVaryingData;
}
/// Returns the vector of patch arrays
const FarPatchTables::PatchArrayVector & GetPatchArrayVector() const {
return _patchArrays;
@ -162,26 +316,38 @@ public:
return _patches;
}
/// XXXX
const int * GetVertexValenceBuffer() const {
return &_vertexValenceBuffer[0];
/// Returns the vertex-valence buffer used for Gregory patch computations
FarPatchTables::VertexValenceTable const & GetVertexValenceTable() const {
return _vertexValenceTable;
}
const unsigned int *GetQuadOffsetBuffer() const {
return &_quadOffsetBuffer[0];
/// Returns the Quad-Offsets buffer used for Gregory patch computations
FarPatchTables::QuadOffsetTable const & GetQuadOffsetTable() const {
return _quadOffsetTable;
}
/// Returns the face-varying data patch table
FarPatchTables::FVarDataTable const & GetFVarData() const {
return _fvarData;
}
/// Returns the number of floats in a datum of the face-varying data table
int GetFVarWidth() const {
return _fvarwidth;
}
/// Returns a map object that can connect a faceId to a list of children patches
const FarPatchTables::PatchMap * GetPatchesMap() const {
return _patchMap;
/// Returns a map that can connect a faceId to a list of children patches
FarPatchMap const & GetPatchMap() const {
return *_patchMap;
}
/// Returns the highest valence of the vertices in the buffers
int GetMaxValence() const {
return _maxValence;
}
protected:
explicit OsdCpuEvalLimitContext(FarMesh<OsdVertex> const * farmesh);
explicit OsdCpuEvalLimitContext(FarMesh<OsdVertex> const * farmesh, bool requireFVarData);
private:
@ -190,22 +356,22 @@ private:
FarPatchTables::PTable _patches; // patch control vertices
std::vector<FarPatchParam::BitField> _patchBitFields; // per-patch parametric info
FarPatchTables::VertexValenceTable _vertexValenceBuffer; // extra Gregory patch data buffers
FarPatchTables::QuadOffsetTable _quadOffsetBuffer;
FarPatchTables::VertexValenceTable _vertexValenceTable; // extra Gregory patch data buffers
FarPatchTables::QuadOffsetTable _quadOffsetTable;
FarPatchTables::PatchMap * _patchMap; // map of the sub-patches given a face index
FarPatchTables::FVarDataTable _fvarData;
OsdVertexBufferDescriptor _inDesc,
_outDesc;
int _maxValence;
float * _inQ, // input vertex data
* _outQ, // output vertex data
* _outdQu, // U derivative of output vertex data
* _outdQv; // V derivative of output vertex data
FarPatchMap * _patchMap; // map of the sub-patches given a face index
VertexData _vertexData; // vertex-interpolated data descriptor
VaryingData _varyingData; // varying-interpolated data descriptor
FaceVaryingData _faceVaryingData; // face-varying-interpolated data descriptor
int _maxValence,
_fvarwidth;
};
} // end namespace OPENSUBDIV_VERSION
using namespace OPENSUBDIV_VERSION;

View File

@ -68,123 +68,153 @@ OsdCpuEvalLimitController::OsdCpuEvalLimitController() {
OsdCpuEvalLimitController::~OsdCpuEvalLimitController() {
}
int
OsdCpuEvalLimitController::_EvalLimitSample( OpenSubdiv::OsdEvalCoords const & coords,
OsdCpuEvalLimitContext const *context,
OsdCpuEvalLimitContext * context,
unsigned int index ) {
int npatches=0;
FarPatchTables::PatchHandle const * patchHandles;
// Get the list of all children patches of the face described in coords
if (not context->GetPatchesMap()->GetChildPatchesHandles(coords.face, &npatches, &patchHandles))
float u=coords.u,
v=coords.v;
FarPatchMap::Handle const * handle = context->GetPatchMap().FindPatch( coords.face, u, v );
// the map may not be able to return a handle if there is a hole or the face
// index is incorrect
if (not handle)
return 0;
FarPatchParam::BitField bits = context->GetPatchBitFields()[ handle->patchIdx ];
// Position lookup pointers at the indexed vertex
float const * inQ = context->GetInputVertexData();
float * outQ = context->GetOutputVertexData() + index * context->GetOutputDesc().stride;
float * outdQu = context->GetOutputVertexDataUDerivative() + index * context->GetOutputDesc().stride;
float * outdQv = context->GetOutputVertexDataVDerivative() + index * context->GetOutputDesc().stride;
bits.Normalize( u, v );
for (int i=0; i<npatches; ++i) {
bits.Rotate( u, v );
FarPatchTables::PatchArray const & parray = context->GetPatchArrayVector()[ handle->patchArrayIdx ];
FarPatchTables::PatchHandle const & handle = patchHandles[i];
unsigned int const * cvs = &context->GetControlVertices()[ parray.GetVertIndex() + handle->vertexOffset ];
OsdCpuEvalLimitContext::VertexData & vertexData = context->GetVertexData();
FarPatchParam::BitField bits = context->GetPatchBitFields()[ handle.serialIndex ];
float frac;
if (bits.NonQuadRoot()) {
frac = 1.0f / float( 1 << (bits.GetDepth()-1) );
} else {
frac = 1.0f / float( 1 << bits.GetDepth() );
}
if (vertexData.IsBound()) {
int offset = vertexData.outDesc.stride * index;
// Are the coordinates within the parametric space covered by the patch ?
float pu = (float)bits.GetU()*frac;
if ( (coords.u < pu) or (coords.u > pu+frac) )
continue;
float pv = (float)bits.GetV()*frac;
if ( (coords.v < pv) or (coords.v > pv+frac) )
continue;
assert( handle.array < context->GetPatchArrayVector().size() );
FarPatchTables::PatchArray const & parray = context->GetPatchArrayVector()[ handle.array ];
unsigned int const * cvs = &context->GetControlVertices()[ parray.GetVertIndex() + handle.vertexOffset ];
// normalize u,v coordinates
float u = (coords.u - pu) / frac,
v = (coords.v - pv) / frac;
assert( (u>=0.0f) and (u<=1.0f) and (v>=0.0f) and (v<=1.0f) );
typedef FarPatchTables::Descriptor PD;
// Rotate u,v to compensate for transition pattern and boundary orientations
switch( bits.GetRotation() ) {
case 0 : break;
case 1 : { float tmp=v; v=1.0f-u; u=tmp; } break;
case 2 : { u=1.0f-u; v=1.0f-v; } break;
case 3 : { float tmp=u; u=1.0f-v; v=tmp; } break;
default:
assert(0);
}
// Based on patch type - go execute interpolation
switch( parray.GetDescriptor().GetType() ) {
case FarPatchTables::REGULAR : { evalBSpline( v, u, cvs,
context->GetInputDesc(),
inQ,
context->GetOutputDesc(),
outQ, outdQu, outdQv);
return 1; }
case FarPatchTables::BOUNDARY : { evalBoundary( v, u, cvs,
context->GetInputDesc(),
inQ,
context->GetOutputDesc(),
outQ, outdQu, outdQv);
return 1; }
case FarPatchTables::CORNER : { evalCorner( v, u, cvs,
context->GetInputDesc(),
inQ,
context->GetOutputDesc(),
outQ, outdQu, outdQv);
return 1; }
case FarPatchTables::GREGORY : { evalGregory(v, u, cvs,
context->GetVertexValenceBuffer(),
context->GetQuadOffsetBuffer() + parray.GetQuadOffsetIndex() + handle.vertexOffset,
context->GetMaxValence(),
context->GetInputDesc(),
inQ,
context->GetOutputDesc(),
outQ, outdQu, outdQv);
return 1; }
case FarPatchTables::REGULAR : if (vertexData.IsBound()) {
evalBSpline( v, u, cvs,
vertexData.inDesc,
vertexData.in.GetData(),
vertexData.outDesc,
vertexData.out.GetData()+offset,
vertexData.outDu.GetData()+offset,
vertexData.outDv.GetData()+offset );
} break;
case FarPatchTables::GREGORY_BOUNDARY : {
evalGregoryBoundary(v, u, cvs,
context->GetVertexValenceBuffer(),
context->GetQuadOffsetBuffer() + parray.GetQuadOffsetIndex() + handle.vertexOffset,
context->GetMaxValence(),
context->GetInputDesc(),
inQ,
context->GetOutputDesc(),
outQ, outdQu, outdQv);
return 1; }
case FarPatchTables::BOUNDARY : if (vertexData.IsBound()) {
evalBoundary( v, u, cvs,
vertexData.inDesc,
vertexData.in.GetData(),
vertexData.outDesc,
vertexData.out.GetData()+offset,
vertexData.outDu.GetData()+offset,
vertexData.outDv.GetData()+offset );
} break;
case FarPatchTables::CORNER : if (vertexData.IsBound()) {
evalCorner( v, u, cvs,
vertexData.inDesc,
vertexData.in.GetData(),
vertexData.outDesc,
vertexData.out.GetData()+offset,
vertexData.outDu.GetData()+offset,
vertexData.outDv.GetData()+offset );
} break;
case FarPatchTables::GREGORY : if (vertexData.IsBound()) {
evalGregory( v, u, cvs,
&context->GetVertexValenceTable()[0],
&context->GetQuadOffsetTable()[ parray.GetQuadOffsetIndex() + handle->vertexOffset ],
context->GetMaxValence(),
vertexData.inDesc,
vertexData.in.GetData(),
vertexData.outDesc,
vertexData.out.GetData()+offset,
vertexData.outDu.GetData()+offset,
vertexData.outDv.GetData()+offset );
} break;
case FarPatchTables::GREGORY_BOUNDARY :
if (vertexData.IsBound()) {
evalGregoryBoundary(v, u, cvs,
&context->GetVertexValenceTable()[0],
&context->GetQuadOffsetTable()[ parray.GetQuadOffsetIndex() + handle->vertexOffset ],
context->GetMaxValence(),
vertexData.inDesc,
vertexData.in.GetData(),
vertexData.outDesc,
vertexData.out.GetData()+offset,
vertexData.outDu.GetData()+offset,
vertexData.outDv.GetData()+offset );
} break;
default:
assert(0);
}
}
}
return 0;
OsdCpuEvalLimitContext::VaryingData & varyingData = context->GetVaryingData();
if (varyingData.IsBound()) {
static int indices[5][4] = { {5, 6,10, 9}, // regular
{1, 2, 6, 5}, // boundary
{1, 2, 5, 4}, // corner
{0, 1, 2, 3}, // gregory
{0, 1, 2, 3} };// gregory boundary
int type = (int)(parray.GetDescriptor().GetType() - FarPatchTables::REGULAR);
int offset = varyingData.outDesc.stride * index;
unsigned int zeroRing[4] = { cvs[indices[type][0]],
cvs[indices[type][1]],
cvs[indices[type][2]],
cvs[indices[type][3]] };
evalBilinear( v, u, zeroRing,
varyingData.inDesc,
varyingData.in.GetData(),
varyingData.outDesc,
varyingData.out.GetData()+offset);
}
// Note : currently we only support bilinear boundary interpolation rules
// for face-varying data. Although Hbr supports 3 additional smooth rule
// sets, the feature-adaptive patch interpolation code currently does not
// support them, and neither does this EvalContext.
OsdCpuEvalLimitContext::FaceVaryingData & faceVaryingData = context->GetFaceVaryingData();
if (faceVaryingData.IsBound()) {
FarPatchTables::FVarDataTable const & fvarData = context->GetFVarData();
if (not fvarData.empty()) {
int offset = faceVaryingData.outDesc.stride * index;
static unsigned int zeroRing[4] = {0,1,2,3};
evalBilinear( v, u, zeroRing,
faceVaryingData.inDesc,
&fvarData[ handle->patchIdx * 4 * context->GetFVarWidth() ],
faceVaryingData.outDesc,
faceVaryingData.out.GetData()+offset);
}
}
return 1;
}
} // end namespace OPENSUBDIV_VERSION

View File

@ -118,9 +118,7 @@ public:
template<class VERTEX_BUFFER, class OUTPUT_BUFFER>
int EvalLimitSample( OpenSubdiv::OsdEvalCoords const & coords,
OsdCpuEvalLimitContext * context,
unsigned int index
) {
unsigned int index ) {
if (not context)
return 0;
@ -132,7 +130,7 @@ public:
private:
int _EvalLimitSample( OpenSubdiv::OsdEvalCoords const & coords,
OsdCpuEvalLimitContext const * context,
OsdCpuEvalLimitContext * context,
unsigned int index );
};

View File

@ -68,9 +68,39 @@
namespace OpenSubdiv {
namespace OPENSUBDIV_VERSION {
void
evalBilinear(float u, float v,
unsigned int const * vertexIndices,
OsdVertexBufferDescriptor const & inDesc,
float const * inQ,
OsdVertexBufferDescriptor const & outDesc,
float * outQ) {
assert( inDesc.length <= (outDesc.stride-outDesc.offset) );
float const * inOffset = inQ + inDesc.offset;
float * Q = outQ + outDesc.offset;
memset(Q, 0, inDesc.length*sizeof(float));
float ou = 1.0f - u,
ov = 1.0f - v,
w[4] = { ov*ou, v*ou, v*u, ov*u };
for (int i=0; i<4; ++i) {
float const * in = inOffset + vertexIndices[i]*inDesc.stride;
for (int k=0; k<inDesc.length; ++k) {
Q[k] += w[i] * in[k];
}
}
}
inline void
evalCubicBSpline(float u, float B[4], float BU[4])
{
evalCubicBSpline(float u, float B[4], float BU[4]) {
float t = u;
float s = 1.0f - u;

View File

@ -64,6 +64,14 @@
namespace OpenSubdiv {
namespace OPENSUBDIV_VERSION {
void
evalBilinear(float u, float v,
unsigned int const * vertexIndices,
OsdVertexBufferDescriptor const & inDesc,
float const * inQ,
OsdVertexBufferDescriptor const & outDesc,
float * outQ);
void
evalBSpline(float u, float v,
unsigned int const * vertexIndices,

View File

@ -55,24 +55,10 @@
// a particular purpose and non-infringement.
//
#if defined(__APPLE__)
#include "TargetConditionals.h"
#if TARGET_OS_IPHONE or TARGET_IPHONE_SIMULATOR
#include <OpenGLES/ES2/gl.h>
#else
#include <OpenGL/gl3.h>
#endif
#elif defined(ANDROID)
#include <GLES2/gl2.h>
#else
#if defined(_WIN32)
#include <windows.h>
#endif
#include <GL/glew.h>
#endif
#include "../osd/cpuGLVertexBuffer.h"
#include "../osd/opengl.h"
#include <string.h>
namespace OpenSubdiv {

View File

@ -59,21 +59,7 @@
#include "../version.h"
#if defined(__APPLE__)
#include "TargetConditionals.h"
#if TARGET_OS_IPHONE or TARGET_IPHONE_SIMULATOR
#include <OpenGLES/ES2/gl.h>
#else
#include <OpenGL/gl3.h>
#endif
#elif defined(ANDROID)
#include <GLES2/gl2.h>
#else
#if defined(_WIN32)
#include <windows.h>
#endif
#include <GL/gl.h>
#endif
#include "../osd/opengl.h"
namespace OpenSubdiv {
namespace OPENSUBDIV_VERSION {

View File

@ -58,6 +58,7 @@
#define OSD_CPU_KERNEL_H
#include "../version.h"
#include "../osd/vertexDescriptor.h"
namespace OpenSubdiv {

View File

@ -55,18 +55,14 @@
// a particular purpose and non-infringement.
//
#if defined(__APPLE__)
#include <OpenGL/gl3.h>
#else
#include <GL/glew.h>
#endif
#include "../osd/cudaGLVertexBuffer.h"
#include "../osd/error.h"
#include "../osd/opengl.h"
#include <cuda_runtime.h>
#include <cuda_gl_interop.h>
#include "../osd/cudaGLVertexBuffer.h"
#include "../osd/error.h"
#include <cassert>
namespace OpenSubdiv {

View File

@ -59,6 +59,11 @@
#include "../version.h"
#include "../osd/opengl.h"
#include <cuda_runtime.h>
#include <cuda_gl_interop.h>
namespace OpenSubdiv {
namespace OPENSUBDIV_VERSION {

View File

@ -58,6 +58,7 @@
#define OSD_DRAW_CONTEXT_H
#include "../version.h"
#include "../far/patchTables.h"
#include <utility>

View File

@ -57,9 +57,10 @@
#ifndef OSD_GCD_KERNEL_H
#define OSD_GCD_KERNEL_H
#include <dispatch/dispatch.h>
#include "../version.h"
#include <dispatch/dispatch.h>
namespace OpenSubdiv {
namespace OPENSUBDIV_VERSION {

View File

@ -49,27 +49,13 @@
// (E) The software is licensed "as-is." You bear the risk of
// using it. The contributors give no express warranties,
#if defined(__APPLE__)
#include "TargetConditionals.h"
#if TARGET_OS_IPHONE or TARGET_IPHONE_SIMULATOR
#include <OpenGLES/ES2/gl.h>
#else
#include <OpenGL/gl3.h>
#endif
#elif defined(ANDROID)
#include <GLES2/gl2.h>
#else
#if defined(_WIN32)
#include <windows.h>
#endif
#include <GL/glew.h>
#endif
#include "../far/dispatcher.h"
#include "../far/loopSubdivisionTables.h"
#include "../osd/glDrawRegistry.h"
#include "../osd/glDrawContext.h"
#include "../osd/opengl.h"
namespace OpenSubdiv {
namespace OPENSUBDIV_VERSION {

View File

@ -57,22 +57,6 @@
#ifndef OSD_GL_DRAW_CONTEXT_H
#define OSD_GL_DRAW_CONTEXT_H
#if defined(__APPLE__)
#include "TargetConditionals.h"
#if TARGET_OS_IPHONE or TARGET_IPHONE_SIMULATOR
#include <OpenGLES/ES2/gl.h>
#else
#include <OpenGL/gl3.h>
#endif
#elif defined(ANDROID)
#include <GLES2/gl2.h>
#else
#if defined(_WIN32)
#include <windows.h>
#endif
#include <GL/gl.h>
#endif
#include "../version.h"
#include "../far/mesh.h"
@ -80,6 +64,8 @@
#include "../osd/drawRegistry.h"
#include "../osd/vertex.h"
#include "../osd/opengl.h"
#include <map>
namespace OpenSubdiv {
@ -157,6 +143,11 @@ public:
return _quadOffsetsTextureBuffer;
}
/// Returns the GL texture buffer containing fvar data
GLuint GetFvarDataTextureBuffer() const {
return _fvarDataTextureBuffer;
}
protected:
GLuint _patchIndexBuffer;

View File

@ -49,25 +49,11 @@
// (E) The software is licensed "as-is." You bear the risk of
// using it. The contributors give no express warranties,
#if defined(__APPLE__)
#include "TargetConditionals.h"
#if TARGET_OS_IPHONE or TARGET_IPHONE_SIMULATOR
#include <OpenGLES/ES2/gl.h>
#else
#include <OpenGL/gl3.h>
#endif
#elif defined(ANDROID)
#include <GLES2/gl2.h>
#else
#if defined(_WIN32)
#include <windows.h>
#endif
#include <GL/glew.h>
#endif
#include "../osd/glDrawRegistry.h"
#include "../osd/error.h"
#include "../osd/opengl.h"
#include <sstream>
namespace OpenSubdiv {

View File

@ -57,28 +57,14 @@
#ifndef OSD_GL_DRAW_REGISTRY_H
#define OSD_GL_DRAW_REGISTRY_H
#if defined(__APPLE__)
#include "TargetConditionals.h"
#if TARGET_OS_IPHONE or TARGET_IPHONE_SIMULATOR
#include <OpenGLES/ES2/gl.h>
#else
#include <OpenGL/gl3.h>
#endif
#elif defined(ANDROID)
#include <GLES2/gl2.h>
#else
#if defined(_WIN32)
#include <windows.h>
#endif
#include <GL/gl.h>
#endif
#include "../version.h"
#include "../far/mesh.h"
#include "../osd/drawRegistry.h"
#include "../osd/vertex.h"
#include "../osd/opengl.h"
#include <map>
namespace OpenSubdiv {

View File

@ -55,14 +55,11 @@
// a particular purpose and non-infringement.
//
#if defined(__APPLE__)
#include <OpenGL/gl3.h>
#else
#include <GL/glew.h>
#endif
#include "../osd/glPtexTexture.h"
#include "../osd/ptexTextureLoader.h"
#include "../osd/opengl.h"
#include <Ptexture.h>
namespace OpenSubdiv {

View File

@ -57,26 +57,12 @@
#ifndef OSD_GL_PTEX_TEXTURE_H
#define OSD_GL_PTEX_TEXTURE_H
#if defined(__APPLE__)
#include "TargetConditionals.h"
#if TARGET_OS_IPHONE or TARGET_IPHONE_SIMULATOR
#include <OpenGLES/ES2/gl.h>
#else
#include <OpenGL/gl3.h>
#endif
#elif defined(ANDROID)
#include <GLES2/gl2.h>
#else
#if defined(_WIN32)
#include <windows.h>
#endif
#include <GL/gl.h>
#endif
#include "../version.h"
#include "../osd/nonCopyable.h"
#include "../osd/opengl.h"
class PtexTexture;
namespace OpenSubdiv {

View File

@ -55,24 +55,10 @@
// a particular purpose and non-infringement.
//
#if defined(__APPLE__)
#include "TargetConditionals.h"
#if TARGET_OS_IPHONE or TARGET_IPHONE_SIMULATOR
#include <OpenGLES/ES2/gl.h>
#else
#include <OpenGL/gl3.h>
#endif
#elif defined(ANDROID)
#include <GLES2/gl2.h>
#else
#if defined(_WIN32)
#include <windows.h>
#endif
#include <GL/glew.h>
#endif
#include "../osd/glVertexBuffer.h"
#include "../osd/opengl.h"
namespace OpenSubdiv {
namespace OPENSUBDIV_VERSION {

View File

@ -57,24 +57,10 @@
#ifndef OSD_GL_VERTEX_BUFFER_H
#define OSD_GL_VERTEX_BUFFER_H
#if defined(__APPLE__)
#include "TargetConditionals.h"
#if TARGET_OS_IPHONE or TARGET_IPHONE_SIMULATOR
#include <OpenGLES/ES2/gl.h>
#else
#include <OpenGL/gl3.h>
#endif
#elif defined(ANDROID)
#include <GLES2/gl2.h>
#else
#if defined(_WIN32)
#include <windows.h>
#endif
#include <GL/gl.h>
#endif
#include "../version.h"
#include "../osd/opengl.h"
namespace OpenSubdiv {
namespace OPENSUBDIV_VERSION {

View File

@ -55,28 +55,14 @@
// a particular purpose and non-infringement.
//
#if defined(__APPLE__)
#include "TargetConditionals.h"
#if TARGET_OS_IPHONE or TARGET_IPHONE_SIMULATOR
#include <OpenGLES/ES2/gl.h>
#else
#include <OpenGL/gl3.h>
#endif
#elif defined(ANDROID)
#include <GLES2/gl2.h>
#else
#if defined(_WIN32)
#include <windows.h>
#endif
#include <GL/glew.h>
#endif
#include "../far/mesh.h"
#include "../osd/debug.h"
#include "../osd/error.h"
#include "../osd/glslComputeContext.h"
#include "../osd/glslKernelBundle.h"
#include "../osd/opengl.h"
namespace OpenSubdiv {
namespace OPENSUBDIV_VERSION {

View File

@ -57,22 +57,6 @@
#ifndef OSD_GLSL_COMPUTE_CONTEXT_H
#define OSD_GLSL_COMPUTE_CONTEXT_H
#if defined(__APPLE__)
#include "TargetConditionals.h"
#if TARGET_OS_IPHONE or TARGET_IPHONE_SIMULATOR
#include <OpenGLES/ES2/gl.h>
#else
#include <OpenGL/gl3.h>
#endif
#elif defined(ANDROID)
#include <GLES2/gl2.h>
#else
#if defined(_WIN32)
#include <windows.h>
#endif
#include <GL/gl.h>
#endif
#include "../version.h"
#include "../far/vertexEditTables.h"
@ -80,6 +64,8 @@
#include "../osd/vertexDescriptor.h"
#include "../osd/nonCopyable.h"
#include "../osd/opengl.h"
#include <vector>
namespace OpenSubdiv {

View File

@ -55,26 +55,12 @@
// a particular purpose and non-infringement.
//
#if defined(__APPLE__)
#include "TargetConditionals.h"
#if TARGET_OS_IPHONE or TARGET_IPHONE_SIMULATOR
#include <OpenGLES/ES2/gl.h>
#else
#include <OpenGL/gl3.h>
#endif
#elif defined(ANDROID)
#include <GLES2/gl2.h>
#else
#if defined(_WIN32)
#include <windows.h>
#endif
#include <GL/glew.h>
#endif
#include "../osd/glslComputeController.h"
#include "../osd/glslComputeContext.h"
#include "../osd/glslKernelBundle.h"
#include "../osd/opengl.h"
#include <algorithm>
#include <cassert>

View File

@ -55,12 +55,6 @@
// a particular purpose and non-infringement.
//
#if defined(__APPLE__)
#include <OpenGL/gl3.h>
#else
#include <GL/glew.h>
#endif
#include <stdio.h>
#ifdef _MSC_VER
#define snprintf _snprintf
@ -73,6 +67,8 @@
#include "../far/subdivisionTables.h"
#include "../osd/opengl.h"
#include <cassert>
namespace OpenSubdiv {

View File

@ -57,28 +57,14 @@
#ifndef OSD_GLSL_COMPUTE_KERNEL_BUNDLE_H
#define OSD_GLSL_COMPUTE_KERNEL_BUNDLE_H
#if defined(__APPLE__)
#include "TargetConditionals.h"
#if TARGET_OS_IPHONE or TARGET_IPHONE_SIMULATOR
#include <OpenGLES/ES2/gl.h>
#else
#include <OpenGL/gl3.h>
#endif
#elif defined(ANDROID)
#include <GLES2/gl2.h>
#else
#if defined(_WIN32)
#include <windows.h>
#endif
#include <GL/gl.h>
#endif
#include "../version.h"
#include "../far/subdivisionTables.h"
#include "../osd/nonCopyable.h"
#include "../osd/vertex.h"
#include "../osd/vertexDescriptor.h"
#include "../osd/opengl.h"
namespace OpenSubdiv {
namespace OPENSUBDIV_VERSION {

View File

@ -55,7 +55,6 @@
// a particular purpose and non-infringement.
//
#extension GL_EXT_gpu_shader4 : require
//----------------------------------------------------------
// Patches.TessVertex
//----------------------------------------------------------
@ -65,15 +64,15 @@ layout (location=0) in vec4 position;
out block {
ControlVertex v;
} output;
} outpt;
void main() {
output.v.position = ModelViewMatrix * position;
outpt.v.position = ModelViewMatrix * position;
OSD_PATCH_CULL_COMPUTE_CLIPFLAGS(position);
#if OSD_NUM_VARYINGS > 0
for (int i = 0; i < OSD_NUM_VARYINGS; ++i)
output.v.varyings[i] = varyings[i];
outpt.v.varyings[i] = varyings[i];
#endif
}
@ -88,11 +87,11 @@ layout(vertices = 16) out;
in block {
ControlVertex v;
} input[];
} inpt[];
out block {
ControlVertex v;
} output[];
} outpt[];
#define ID gl_InvocationID
@ -108,7 +107,7 @@ void main()
H[l] = vec3(0,0,0);
for (int k=0; k<4; k++) {
float c = Q[i][k];
H[l] += c*input[l*4 + k].v.position.xyz;
H[l] += c*inpt[l*4 + k].v.position.xyz;
}
}
@ -117,28 +116,28 @@ void main()
pos += B[j][k]*H[k];
}
output[ID].v.position = vec4(pos, 1.0);
outpt[ID].v.position = vec4(pos, 1.0);
int patchLevel = GetPatchLevel();
// +0.5 to avoid interpolation error of integer value
output[ID].v.patchCoord = vec4(0, 0,
patchLevel+0.5,
gl_PrimitiveID+LevelBase+0.5);
outpt[ID].v.patchCoord = vec4(0, 0,
patchLevel+0.5,
gl_PrimitiveID+LevelBase+0.5);
OSD_COMPUTE_PTEX_COORD_TESSCONTROL_SHADER;
if (ID == 0) {
OSD_PATCH_CULL(12);
#if OSD_ENABLE_SCREENSPACE_TESSELLATION
#ifdef OSD_ENABLE_SCREENSPACE_TESSELLATION
gl_TessLevelOuter[0] =
TessAdaptive(input[1].v.position.xyz, input[2].v.position.xyz, patchLevel);
TessAdaptive(inpt[1].v.position.xyz, inpt[2].v.position.xyz, patchLevel);
gl_TessLevelOuter[1] =
TessAdaptive(input[2].v.position.xyz, input[6].v.position.xyz, patchLevel);
TessAdaptive(inpt[2].v.position.xyz, inpt[6].v.position.xyz, patchLevel);
gl_TessLevelOuter[2] =
TessAdaptive(input[5].v.position.xyz, input[6].v.position.xyz, patchLevel);
TessAdaptive(inpt[5].v.position.xyz, inpt[6].v.position.xyz, patchLevel);
gl_TessLevelOuter[3] =
TessAdaptive(input[1].v.position.xyz, input[5].v.position.xyz, patchLevel);
TessAdaptive(inpt[1].v.position.xyz, inpt[5].v.position.xyz, patchLevel);
gl_TessLevelInner[0] =
max(gl_TessLevelOuter[1], gl_TessLevelOuter[3]);
gl_TessLevelInner[1] =
@ -166,12 +165,11 @@ layout(equal_spacing) in;
in block {
ControlVertex v;
int clipFlag;
} input[];
} inpt[];
out block {
OutputVertex v;
} output;
} outpt;
void main()
{
@ -190,7 +188,7 @@ void main()
DUCP[i] = vec3(0.0f, 0.0f, 0.0f);
for (int j=0; j<4; ++j) {
vec3 A = input[4*i + j].v.position.xyz;
vec3 A = inpt[4*i + j].v.position.xyz;
BUCP[i] += A * B[j];
DUCP[i] += A * D[j];
@ -211,19 +209,19 @@ void main()
*/
vec3 WorldPos, Tangent, BiTangent;
vec3 cp[16];
for(int i = 0; i < 16; ++i) cp[i] = input[i].v.position.xyz;
for(int i = 0; i < 16; ++i) cp[i] = inpt[i].v.position.xyz;
EvalBSpline(gl_TessCoord.xy, cp, WorldPos, Tangent, BiTangent);
vec3 normal = normalize(cross(Tangent, BiTangent));
output.v.position = vec4(WorldPos, 1.0f);
output.v.normal = normal;
outpt.v.position = vec4(WorldPos, 1.0f);
outpt.v.normal = normal;
BiTangent = -BiTangent; // BiTangent will be used in following macro
output.v.tangent = BiTangent;
outpt.v.tangent = BiTangent;
output.v.patchCoord = input[0].v.patchCoord;
output.v.patchCoord.xy = vec2(1.0-v, u);
outpt.v.patchCoord = inpt[0].v.patchCoord;
outpt.v.patchCoord.xy = vec2(1.0-v, u);
OSD_COMPUTE_PTEX_COORD_TESSEVAL_SHADER;
@ -247,11 +245,11 @@ layout (location=2) in vec4 color;
out block {
OutputVertex v;
} output;
} outpt;
void main() {
gl_Position = ModelViewProjectionMatrix * position;
output.v.color = color;
outpt.v.color = color;
}
#endif
@ -263,9 +261,9 @@ void main() {
in block {
OutputVertex v;
} input;
} inpt;
void main() {
gl_FragColor = input.v.color;
gl_FragColor = inpt.v.color;
}
#endif

View File

@ -55,7 +55,6 @@
// a particular purpose and non-infringement.
//
#extension GL_EXT_gpu_shader4 : require
//----------------------------------------------------------
// Patches.TessVertexBoundaryGregory
//----------------------------------------------------------
@ -68,22 +67,22 @@ layout (location=0) in vec4 position;
out block {
GregControlVertex v;
} output;
} outpt;
void main()
{
int vID = gl_VertexID;
output.v.hullPosition = (ModelViewMatrix * position).xyz;
outpt.v.hullPosition = (ModelViewMatrix * position).xyz;
OSD_PATCH_CULL_COMPUTE_CLIPFLAGS(position);
int valence = texelFetchBuffer(g_ValenceBuffer,int(vID * (2 * OSD_MAX_VALENCE + 1))).x;
output.v.valence = int(valence);
int valence = texelFetch(g_ValenceBuffer,int(vID * (2 * OSD_MAX_VALENCE + 1))).x;
outpt.v.valence = int(valence);
uint ivalence = uint(abs(valence));
vec3 f[OSD_MAX_VALENCE];
vec3 pos = position.xyz;
output.v.org = position.xyz;
outpt.v.org = position.xyz;
vec3 opos = vec3(0,0,0);
int boundaryEdgeNeighbors[2];
@ -96,8 +95,8 @@ void main()
uint ip=(i+1)%ivalence;
bool isBoundaryNeighbor = false;
uint idx_neighbor = uint(texelFetchBuffer(g_ValenceBuffer, int(vID * (2*OSD_MAX_VALENCE+1) + 2*i + 0 + 1)).x);
int valenceNeighbor = texelFetchBuffer(g_ValenceBuffer,int(idx_neighbor * (2 * OSD_MAX_VALENCE + 1))).x;
uint idx_neighbor = uint(texelFetch(g_ValenceBuffer, int(vID * (2*OSD_MAX_VALENCE+1) + 2*i + 0 + 1)).x);
int valenceNeighbor = texelFetch(g_ValenceBuffer,int(idx_neighbor * (2 * OSD_MAX_VALENCE + 1))).x;
if (valenceNeighbor < 0) {
isBoundaryNeighbor = true;
@ -116,51 +115,51 @@ void main()
}
vec3 neighbor =
vec3(texelFetchBuffer(g_VertexBuffer, int(OSD_NUM_ELEMENTS*idx_neighbor)).x,
texelFetchBuffer(g_VertexBuffer, int(OSD_NUM_ELEMENTS*idx_neighbor+1)).x,
texelFetchBuffer(g_VertexBuffer, int(OSD_NUM_ELEMENTS*idx_neighbor+2)).x);
vec3(texelFetch(g_VertexBuffer, int(OSD_NUM_ELEMENTS*idx_neighbor)).x,
texelFetch(g_VertexBuffer, int(OSD_NUM_ELEMENTS*idx_neighbor+1)).x,
texelFetch(g_VertexBuffer, int(OSD_NUM_ELEMENTS*idx_neighbor+2)).x);
uint idx_diagonal = uint(texelFetchBuffer(g_ValenceBuffer, int(vID * (2*OSD_MAX_VALENCE+1) + 2*i + 1 + 1)).x);
uint idx_diagonal = uint(texelFetch(g_ValenceBuffer, int(vID * (2*OSD_MAX_VALENCE+1) + 2*i + 1 + 1)).x);
vec3 diagonal =
vec3(texelFetchBuffer(g_VertexBuffer, int(OSD_NUM_ELEMENTS*idx_diagonal)).x,
texelFetchBuffer(g_VertexBuffer, int(OSD_NUM_ELEMENTS*idx_diagonal+1)).x,
texelFetchBuffer(g_VertexBuffer, int(OSD_NUM_ELEMENTS*idx_diagonal+2)).x);
vec3(texelFetch(g_VertexBuffer, int(OSD_NUM_ELEMENTS*idx_diagonal)).x,
texelFetch(g_VertexBuffer, int(OSD_NUM_ELEMENTS*idx_diagonal+1)).x,
texelFetch(g_VertexBuffer, int(OSD_NUM_ELEMENTS*idx_diagonal+2)).x);
uint idx_neighbor_p = uint(texelFetchBuffer(g_ValenceBuffer, int(vID * (2*OSD_MAX_VALENCE+1) + 2*ip + 0 + 1)).x);
uint idx_neighbor_p = uint(texelFetch(g_ValenceBuffer, int(vID * (2*OSD_MAX_VALENCE+1) + 2*ip + 0 + 1)).x);
vec3 neighbor_p =
vec3(texelFetchBuffer(g_VertexBuffer, int(OSD_NUM_ELEMENTS*idx_neighbor_p)).x,
texelFetchBuffer(g_VertexBuffer, int(OSD_NUM_ELEMENTS*idx_neighbor_p+1)).x,
texelFetchBuffer(g_VertexBuffer, int(OSD_NUM_ELEMENTS*idx_neighbor_p+2)).x);
vec3(texelFetch(g_VertexBuffer, int(OSD_NUM_ELEMENTS*idx_neighbor_p)).x,
texelFetch(g_VertexBuffer, int(OSD_NUM_ELEMENTS*idx_neighbor_p+1)).x,
texelFetch(g_VertexBuffer, int(OSD_NUM_ELEMENTS*idx_neighbor_p+2)).x);
uint idx_neighbor_m = uint(texelFetchBuffer(g_ValenceBuffer, int(vID * (2*OSD_MAX_VALENCE+1) + 2*im + 0 + 1)).x);
uint idx_neighbor_m = uint(texelFetch(g_ValenceBuffer, int(vID * (2*OSD_MAX_VALENCE+1) + 2*im + 0 + 1)).x);
vec3 neighbor_m =
vec3(texelFetchBuffer(g_VertexBuffer, int(OSD_NUM_ELEMENTS*idx_neighbor_m)).x,
texelFetchBuffer(g_VertexBuffer, int(OSD_NUM_ELEMENTS*idx_neighbor_m+1)).x,
texelFetchBuffer(g_VertexBuffer, int(OSD_NUM_ELEMENTS*idx_neighbor_m+2)).x);
vec3(texelFetch(g_VertexBuffer, int(OSD_NUM_ELEMENTS*idx_neighbor_m)).x,
texelFetch(g_VertexBuffer, int(OSD_NUM_ELEMENTS*idx_neighbor_m+1)).x,
texelFetch(g_VertexBuffer, int(OSD_NUM_ELEMENTS*idx_neighbor_m+2)).x);
uint idx_diagonal_m = uint(texelFetchBuffer(g_ValenceBuffer, int(vID * (2*OSD_MAX_VALENCE+1) + 2*im + 1 + 1)).x);
uint idx_diagonal_m = uint(texelFetch(g_ValenceBuffer, int(vID * (2*OSD_MAX_VALENCE+1) + 2*im + 1 + 1)).x);
vec3 diagonal_m =
vec3(texelFetchBuffer(g_VertexBuffer, int(OSD_NUM_ELEMENTS*idx_diagonal_m)).x,
texelFetchBuffer(g_VertexBuffer, int(OSD_NUM_ELEMENTS*idx_diagonal_m+1)).x,
texelFetchBuffer(g_VertexBuffer, int(OSD_NUM_ELEMENTS*idx_diagonal_m+2)).x);
vec3(texelFetch(g_VertexBuffer, int(OSD_NUM_ELEMENTS*idx_diagonal_m)).x,
texelFetch(g_VertexBuffer, int(OSD_NUM_ELEMENTS*idx_diagonal_m+1)).x,
texelFetch(g_VertexBuffer, int(OSD_NUM_ELEMENTS*idx_diagonal_m+2)).x);
f[i] = (pos * float(ivalence) + (neighbor_p + neighbor)*2.0f + diagonal) / (float(ivalence)+5.0f);
opos += f[i];
output.v.r[i] = (neighbor_p-neighbor_m)/3.0f + (diagonal - diagonal_m)/6.0f;
outpt.v.r[i] = (neighbor_p-neighbor_m)/3.0f + (diagonal - diagonal_m)/6.0f;
}
opos /= ivalence;
output.v.position = vec4(opos, 1.0f).xyz;
output.v.zerothNeighbor = zerothNeighbor;
outpt.v.position = vec4(opos, 1.0f).xyz;
outpt.v.zerothNeighbor = zerothNeighbor;
#if OSD_NUM_VARYINGS > 0
for (int i = 0; i < OSD_NUM_VARYINGS; ++i)
output.v.varyings[i] = varyings[i];
outpt.v.varyings[i] = varyings[i];
#endif
@ -169,39 +168,39 @@ void main()
}
vec3 e;
output.v.e0 = vec3(0,0,0);
output.v.e1 = vec3(0,0,0);
outpt.v.e0 = vec3(0,0,0);
outpt.v.e1 = vec3(0,0,0);
for(uint i=0; i<ivalence; ++i) {
uint im = (i + ivalence -1) % ivalence;
e = 0.5f * (f[i] + f[im]);
output.v.e0 += csf(ivalence-3, 2*i) *e;
output.v.e1 += csf(ivalence-3, 2*i + 1)*e;
outpt.v.e0 += csf(ivalence-3, 2*i) *e;
outpt.v.e1 += csf(ivalence-3, 2*i + 1)*e;
}
output.v.e0 *= ef[ivalence - 3];
output.v.e1 *= ef[ivalence - 3];
outpt.v.e0 *= ef[ivalence - 3];
outpt.v.e1 *= ef[ivalence - 3];
if (valence < 0) {
if (ivalence > 2) {
output.v.position = (
vec3(texelFetchBuffer(g_VertexBuffer, int(OSD_NUM_ELEMENTS*boundaryEdgeNeighbors[0])).x,
texelFetchBuffer(g_VertexBuffer, int(OSD_NUM_ELEMENTS*boundaryEdgeNeighbors[0]+1)).x,
texelFetchBuffer(g_VertexBuffer, int(OSD_NUM_ELEMENTS*boundaryEdgeNeighbors[0]+2)).x) +
vec3(texelFetchBuffer(g_VertexBuffer, int(OSD_NUM_ELEMENTS*boundaryEdgeNeighbors[1])).x,
texelFetchBuffer(g_VertexBuffer, int(OSD_NUM_ELEMENTS*boundaryEdgeNeighbors[1]+1)).x,
texelFetchBuffer(g_VertexBuffer, int(OSD_NUM_ELEMENTS*boundaryEdgeNeighbors[1]+2)).x) +
outpt.v.position = (
vec3(texelFetch(g_VertexBuffer, int(OSD_NUM_ELEMENTS*boundaryEdgeNeighbors[0])).x,
texelFetch(g_VertexBuffer, int(OSD_NUM_ELEMENTS*boundaryEdgeNeighbors[0]+1)).x,
texelFetch(g_VertexBuffer, int(OSD_NUM_ELEMENTS*boundaryEdgeNeighbors[0]+2)).x) +
vec3(texelFetch(g_VertexBuffer, int(OSD_NUM_ELEMENTS*boundaryEdgeNeighbors[1])).x,
texelFetch(g_VertexBuffer, int(OSD_NUM_ELEMENTS*boundaryEdgeNeighbors[1]+1)).x,
texelFetch(g_VertexBuffer, int(OSD_NUM_ELEMENTS*boundaryEdgeNeighbors[1]+2)).x) +
4.0f * pos)/6.0f;
} else {
output.v.position = pos;
outpt.v.position = pos;
}
output.v.e0 = (
vec3(texelFetchBuffer(g_VertexBuffer, int(OSD_NUM_ELEMENTS*boundaryEdgeNeighbors[0])).x,
texelFetchBuffer(g_VertexBuffer, int(OSD_NUM_ELEMENTS*boundaryEdgeNeighbors[0]+1)).x,
texelFetchBuffer(g_VertexBuffer, int(OSD_NUM_ELEMENTS*boundaryEdgeNeighbors[0]+2)).x) -
vec3(texelFetchBuffer(g_VertexBuffer, int(OSD_NUM_ELEMENTS*boundaryEdgeNeighbors[1])).x,
texelFetchBuffer(g_VertexBuffer, int(OSD_NUM_ELEMENTS*boundaryEdgeNeighbors[1]+1)).x,
texelFetchBuffer(g_VertexBuffer, int(OSD_NUM_ELEMENTS*boundaryEdgeNeighbors[1]+2)).x)
outpt.v.e0 = (
vec3(texelFetch(g_VertexBuffer, int(OSD_NUM_ELEMENTS*boundaryEdgeNeighbors[0])).x,
texelFetch(g_VertexBuffer, int(OSD_NUM_ELEMENTS*boundaryEdgeNeighbors[0]+1)).x,
texelFetch(g_VertexBuffer, int(OSD_NUM_ELEMENTS*boundaryEdgeNeighbors[0]+2)).x) -
vec3(texelFetch(g_VertexBuffer, int(OSD_NUM_ELEMENTS*boundaryEdgeNeighbors[1])).x,
texelFetch(g_VertexBuffer, int(OSD_NUM_ELEMENTS*boundaryEdgeNeighbors[1]+1)).x,
texelFetch(g_VertexBuffer, int(OSD_NUM_ELEMENTS*boundaryEdgeNeighbors[1]+2)).x)
)/6.0;
float k = float(float(ivalence) - 1.0f); //k is the number of faces
@ -212,20 +211,20 @@ void main()
float beta_0 = s/(3.0f*k + c);
int idx_diagonal = texelFetchBuffer(g_ValenceBuffer,int((vID) * (2*OSD_MAX_VALENCE+1) + 2*zerothNeighbor + 1 + 1)).x;
int idx_diagonal = texelFetch(g_ValenceBuffer,int((vID) * (2*OSD_MAX_VALENCE+1) + 2*zerothNeighbor + 1 + 1)).x;
idx_diagonal = abs(idx_diagonal);
vec3 diagonal =
vec3(texelFetchBuffer(g_VertexBuffer, int(OSD_NUM_ELEMENTS*idx_diagonal)).x,
texelFetchBuffer(g_VertexBuffer, int(OSD_NUM_ELEMENTS*idx_diagonal+1)).x,
texelFetchBuffer(g_VertexBuffer, int(OSD_NUM_ELEMENTS*idx_diagonal+2)).x);
vec3(texelFetch(g_VertexBuffer, int(OSD_NUM_ELEMENTS*idx_diagonal)).x,
texelFetch(g_VertexBuffer, int(OSD_NUM_ELEMENTS*idx_diagonal+1)).x,
texelFetch(g_VertexBuffer, int(OSD_NUM_ELEMENTS*idx_diagonal+2)).x);
output.v.e1 = gamma * pos +
alpha_0k * vec3(texelFetchBuffer(g_VertexBuffer, int(OSD_NUM_ELEMENTS*boundaryEdgeNeighbors[0])).x,
texelFetchBuffer(g_VertexBuffer, int(OSD_NUM_ELEMENTS*boundaryEdgeNeighbors[0]+1)).x,
texelFetchBuffer(g_VertexBuffer, int(OSD_NUM_ELEMENTS*boundaryEdgeNeighbors[0]+2)).x) +
alpha_0k * vec3(texelFetchBuffer(g_VertexBuffer, int(OSD_NUM_ELEMENTS*boundaryEdgeNeighbors[1])).x,
texelFetchBuffer(g_VertexBuffer, int(OSD_NUM_ELEMENTS*boundaryEdgeNeighbors[1]+1)).x,
texelFetchBuffer(g_VertexBuffer, int(OSD_NUM_ELEMENTS*boundaryEdgeNeighbors[1]+2)).x) +
outpt.v.e1 = gamma * pos +
alpha_0k * vec3(texelFetch(g_VertexBuffer, int(OSD_NUM_ELEMENTS*boundaryEdgeNeighbors[0])).x,
texelFetch(g_VertexBuffer, int(OSD_NUM_ELEMENTS*boundaryEdgeNeighbors[0]+1)).x,
texelFetch(g_VertexBuffer, int(OSD_NUM_ELEMENTS*boundaryEdgeNeighbors[0]+2)).x) +
alpha_0k * vec3(texelFetch(g_VertexBuffer, int(OSD_NUM_ELEMENTS*boundaryEdgeNeighbors[1])).x,
texelFetch(g_VertexBuffer, int(OSD_NUM_ELEMENTS*boundaryEdgeNeighbors[1]+1)).x,
texelFetch(g_VertexBuffer, int(OSD_NUM_ELEMENTS*boundaryEdgeNeighbors[1]+2)).x) +
beta_0 * diagonal;
for (uint x=1; x<ivalence - 1; ++x) {
@ -233,25 +232,25 @@ void main()
float alpha = (4.0f*sin((M_PI * float(x))/k))/(3.0f*k+c);
float beta = (sin((M_PI * float(x))/k) + sin((M_PI * float(x+1))/k))/(3.0f*k+c);
int idx_neighbor = texelFetchBuffer(g_ValenceBuffer, int((vID) * (2*OSD_MAX_VALENCE+1) + 2*curri + 0 + 1)).x;
int idx_neighbor = texelFetch(g_ValenceBuffer, int((vID) * (2*OSD_MAX_VALENCE+1) + 2*curri + 0 + 1)).x;
idx_neighbor = abs(idx_neighbor);
vec3 neighbor =
vec3(texelFetchBuffer(g_VertexBuffer, int(OSD_NUM_ELEMENTS*idx_neighbor)).x,
texelFetchBuffer(g_VertexBuffer, int(OSD_NUM_ELEMENTS*idx_neighbor+1)).x,
texelFetchBuffer(g_VertexBuffer, int(OSD_NUM_ELEMENTS*idx_neighbor+2)).x);
vec3(texelFetch(g_VertexBuffer, int(OSD_NUM_ELEMENTS*idx_neighbor)).x,
texelFetch(g_VertexBuffer, int(OSD_NUM_ELEMENTS*idx_neighbor+1)).x,
texelFetch(g_VertexBuffer, int(OSD_NUM_ELEMENTS*idx_neighbor+2)).x);
idx_diagonal = texelFetchBuffer(g_ValenceBuffer, int((vID) * (2*OSD_MAX_VALENCE+1) + 2*curri + 1 + 1)).x;
idx_diagonal = texelFetch(g_ValenceBuffer, int((vID) * (2*OSD_MAX_VALENCE+1) + 2*curri + 1 + 1)).x;
diagonal =
vec3(texelFetchBuffer(g_VertexBuffer, int(OSD_NUM_ELEMENTS*idx_diagonal)).x,
texelFetchBuffer(g_VertexBuffer, int(OSD_NUM_ELEMENTS*idx_diagonal+1)).x,
texelFetchBuffer(g_VertexBuffer, int(OSD_NUM_ELEMENTS*idx_diagonal+2)).x);
vec3(texelFetch(g_VertexBuffer, int(OSD_NUM_ELEMENTS*idx_diagonal)).x,
texelFetch(g_VertexBuffer, int(OSD_NUM_ELEMENTS*idx_diagonal+1)).x,
texelFetch(g_VertexBuffer, int(OSD_NUM_ELEMENTS*idx_diagonal+2)).x);
output.v.e1 += alpha * neighbor + beta * diagonal;
outpt.v.e1 += alpha * neighbor + beta * diagonal;
}
output.v.e1 /= 3.0f;
outpt.v.e1 /= 3.0f;
}
}
#endif
@ -267,11 +266,11 @@ uniform isamplerBuffer g_QuadOffsetBuffer;
in block {
GregControlVertex v;
} input[];
} inpt[];
out block {
GregEvalVertex v;
} output[];
} outpt[];
#define ID gl_InvocationID
@ -280,17 +279,17 @@ void main()
uint i = gl_InvocationID;
uint ip = (i+1)%4;
uint im = (i+3)%4;
uint n = uint(abs(input[i].v.valence));
uint ivalence = abs(input[i].v.valence);
uint n = uint(abs(inpt[i].v.valence));
uint ivalence = abs(inpt[i].v.valence);
int base = GregoryQuadOffsetBase;
output[ID].v.position = input[ID].v.position;
outpt[ID].v.position = inpt[ID].v.position;
uint start = texelFetchBuffer(g_QuadOffsetBuffer, int(4*gl_PrimitiveID+base + i)).x & 0x00ff;
uint prev = uint(texelFetchBuffer(g_QuadOffsetBuffer, int(4*gl_PrimitiveID+base + i)).x) & 0xff00;
uint start = uint(texelFetch(g_QuadOffsetBuffer, int(4*gl_PrimitiveID+base + i)).x) & 0x00ffu;
uint prev = uint(texelFetch(g_QuadOffsetBuffer, int(4*gl_PrimitiveID+base + i)).x) & 0xff00u;
prev=uint(prev/256);
uint np = abs(input[ip].v.valence);
uint nm = abs(input[im].v.valence);
uint np = abs(inpt[ip].v.valence);
uint nm = abs(inpt[im].v.valence);
// Control Vertices based on :
// "Approximating Subdivision Surfaces with Gregory Patches for Hardware Tessellation"
@ -321,103 +320,103 @@ void main()
vec3 Fp = vec3(0.0f,0.0f,0.0f);
vec3 Fm = vec3(0.0f,0.0f,0.0f);
uint prev_p = uint(texelFetchBuffer(g_QuadOffsetBuffer, int(4*gl_PrimitiveID+base + ip)).x)&0xff00;
uint prev_p = uint(texelFetch(g_QuadOffsetBuffer, int(4*gl_PrimitiveID+base + ip)).x) & 0xff00u;
prev_p=uint(prev_p/256);
vec3 Em_ip;
if (input[ip].v.valence < -2) {
uint j = (np + prev_p - input[ip].v.zerothNeighbor) % np;
Em_ip = input[ip].v.position + cos((M_PI*j)/float(np-1))*input[ip].v.e0 + sin((M_PI*j)/float(np-1))*input[ip].v.e1;
if (inpt[ip].v.valence < -2) {
uint j = (np + prev_p - inpt[ip].v.zerothNeighbor) % np;
Em_ip = inpt[ip].v.position + cos((M_PI*j)/float(np-1))*inpt[ip].v.e0 + sin((M_PI*j)/float(np-1))*inpt[ip].v.e1;
} else {
Em_ip = input[ip].v.position + input[ip].v.e0*csf(np-3,2*prev_p) + input[ip].v.e1*csf(np-3,2*prev_p+1);
Em_ip = inpt[ip].v.position + inpt[ip].v.e0*csf(np-3,2*prev_p) + inpt[ip].v.e1*csf(np-3,2*prev_p+1);
}
uint start_m = uint(texelFetchBuffer(g_QuadOffsetBuffer, int(4*gl_PrimitiveID+base + im)).x)&0x00ff;
uint start_m = uint(texelFetch(g_QuadOffsetBuffer, int(4*gl_PrimitiveID+base + im)).x) & 0x00ffu;
vec3 Ep_im;
if (input[im].v.valence < -2) {
uint j = (nm + start_m - input[im].v.zerothNeighbor) % nm;
Ep_im = input[im].v.position + cos((M_PI*j)/float(nm-1))*input[im].v.e0 + sin((M_PI*j)/float(nm-1))*input[im].v.e1;
if (inpt[im].v.valence < -2) {
uint j = (nm + start_m - inpt[im].v.zerothNeighbor) % nm;
Ep_im = inpt[im].v.position + cos((M_PI*j)/float(nm-1))*inpt[im].v.e0 + sin((M_PI*j)/float(nm-1))*inpt[im].v.e1;
} else {
Ep_im = input[im].v.position + input[im].v.e0*csf(nm-3,2*start_m) + input[im].v.e1*csf(nm-3,2*start_m+1);
Ep_im = inpt[im].v.position + inpt[im].v.e0*csf(nm-3,2*start_m) + inpt[im].v.e1*csf(nm-3,2*start_m+1);
}
if (input[i].v.valence < 0) {
if (inpt[i].v.valence < 0) {
n = (n-1)*2;
}
if (input[im].v.valence < 0) {
if (inpt[im].v.valence < 0) {
nm = (nm-1)*2;
}
if (input[ip].v.valence < 0) {
if (inpt[ip].v.valence < 0) {
np = (np-1)*2;
}
if (input[i].v.valence > 2) {
Ep = input[i].v.position + (input[i].v.e0*csf(n-3,2*start) + input[i].v.e1*csf(n-3,2*start+1));
Em = input[i].v.position + (input[i].v.e0*csf(n-3,2*prev) + input[i].v.e1*csf(n-3,2*prev+1));
if (inpt[i].v.valence > 2) {
Ep = inpt[i].v.position + (inpt[i].v.e0*csf(n-3,2*start) + inpt[i].v.e1*csf(n-3,2*start+1));
Em = inpt[i].v.position + (inpt[i].v.e0*csf(n-3,2*prev) + inpt[i].v.e1*csf(n-3,2*prev+1));
float s1=3-2*csf(n-3,2)-csf(np-3,2);
float s2=2*csf(n-3,2);
Fp = (csf(np-3,2)*input[i].v.position + s1*Ep + s2*Em_ip + input[i].v.r[start])/3.0f;
Fp = (csf(np-3,2)*inpt[i].v.position + s1*Ep + s2*Em_ip + inpt[i].v.r[start])/3.0f;
s1 = 3.0f-2.0f*cos(2.0f*M_PI/n)-cos(2*M_PI/nm);
Fm = (csf(nm-3,2)*input[i].v.position + s1*Em + s2*Ep_im - input[i].v.r[prev])/3.0f;
Fm = (csf(nm-3,2)*inpt[i].v.position + s1*Em + s2*Ep_im - inpt[i].v.r[prev])/3.0f;
} else if (input[i].v.valence < -2) {
uint j = (ivalence + start - input[i].v.zerothNeighbor) % ivalence;
} else if (inpt[i].v.valence < -2) {
uint j = (ivalence + start - inpt[i].v.zerothNeighbor) % ivalence;
Ep = input[i].v.position + cos((M_PI*j)/float(ivalence-1))*input[i].v.e0 + sin((M_PI*j)/float(ivalence-1))*input[i].v.e1;
j = (ivalence + prev - input[i].v.zerothNeighbor) % ivalence;
Em = input[i].v.position + cos((M_PI*j)/float(ivalence-1))*input[i].v.e0 + sin((M_PI*j)/float(ivalence-1))*input[i].v.e1;
Ep = inpt[i].v.position + cos((M_PI*j)/float(ivalence-1))*inpt[i].v.e0 + sin((M_PI*j)/float(ivalence-1))*inpt[i].v.e1;
j = (ivalence + prev - inpt[i].v.zerothNeighbor) % ivalence;
Em = inpt[i].v.position + cos((M_PI*j)/float(ivalence-1))*inpt[i].v.e0 + sin((M_PI*j)/float(ivalence-1))*inpt[i].v.e1;
vec3 Rp = ((-2.0f * input[i].v.org - 1.0f * input[im].v.org) + (2.0f * input[ip].v.org + 1.0f * input[(i+2)%4].v.org))/3.0f;
vec3 Rm = ((-2.0f * input[i].v.org - 1.0f * input[ip].v.org) + (2.0f * input[im].v.org + 1.0f * input[(i+2)%4].v.org))/3.0f;
vec3 Rp = ((-2.0f * inpt[i].v.org - 1.0f * inpt[im].v.org) + (2.0f * inpt[ip].v.org + 1.0f * inpt[(i+2)%4].v.org))/3.0f;
vec3 Rm = ((-2.0f * inpt[i].v.org - 1.0f * inpt[ip].v.org) + (2.0f * inpt[im].v.org + 1.0f * inpt[(i+2)%4].v.org))/3.0f;
float s1=3-2*csf(n-3,2)-csf(np-3,2);
float s2=2*csf(n-3,2);
Fp = (csf(np-3,2)*input[i].v.position + s1*Ep + s2*Em_ip + input[i].v.r[start])/3.0f;
Fp = (csf(np-3,2)*inpt[i].v.position + s1*Ep + s2*Em_ip + inpt[i].v.r[start])/3.0f;
s1 = 3.0f-2.0f*cos(2.0f*M_PI/n)-cos(2.0f*M_PI/nm);
Fm = (csf(nm-3,2)*input[i].v.position + s1*Em + s2*Ep_im - input[i].v.r[prev])/3.0f;
Fm = (csf(nm-3,2)*inpt[i].v.position + s1*Em + s2*Ep_im - inpt[i].v.r[prev])/3.0f;
if (input[im].v.valence < 0) {
if (inpt[im].v.valence < 0) {
s1=3-2*csf(n-3,2)-csf(np-3,2);
Fp = Fm = (csf(np-3,2)*input[i].v.position + s1*Ep + s2*Em_ip + input[i].v.r[start])/3.0f;
} else if (input[ip].v.valence < 0) {
Fp = Fm = (csf(np-3,2)*inpt[i].v.position + s1*Ep + s2*Em_ip + inpt[i].v.r[start])/3.0f;
} else if (inpt[ip].v.valence < 0) {
s1 = 3.0f-2.0f*cos(2.0f*M_PI/n)-cos(2.0f*M_PI/nm);
Fm = Fp = (csf(nm-3,2)*input[i].v.position + s1*Em + s2*Ep_im - input[i].v.r[prev])/3.0f;
Fm = Fp = (csf(nm-3,2)*inpt[i].v.position + s1*Em + s2*Ep_im - inpt[i].v.r[prev])/3.0f;
}
} else if (input[i].v.valence == -2) {
Ep = (2.0f * input[i].v.org + input[ip].v.org)/3.0f;
Em = (2.0f * input[i].v.org + input[im].v.org)/3.0f;
Fp = Fm = (4.0f * input[i].v.org + input[(i+2)%n].v.org + 2.0f * input[ip].v.org + 2.0f * input[im].v.org)/9.0f;
} else if (inpt[i].v.valence == -2) {
Ep = (2.0f * inpt[i].v.org + inpt[ip].v.org)/3.0f;
Em = (2.0f * inpt[i].v.org + inpt[im].v.org)/3.0f;
Fp = Fm = (4.0f * inpt[i].v.org + inpt[(i+2)%n].v.org + 2.0f * inpt[ip].v.org + 2.0f * inpt[im].v.org)/9.0f;
}
output[ID].v.Ep = Ep;
output[ID].v.Em = Em;
output[ID].v.Fp = Fp;
output[ID].v.Fm = Fm;
outpt[ID].v.Ep = Ep;
outpt[ID].v.Em = Em;
outpt[ID].v.Fp = Fp;
outpt[ID].v.Fm = Fm;
int patchLevel = GetPatchLevel();
output[ID].v.patchCoord = vec4(0, 0,
patchLevel+0.5f,
gl_PrimitiveID+LevelBase+0.5f);
outpt[ID].v.patchCoord = vec4(0, 0,
patchLevel+0.5f,
gl_PrimitiveID+LevelBase+0.5f);
OSD_COMPUTE_PTEX_COORD_TESSCONTROL_SHADER;
if (ID == 0) {
OSD_PATCH_CULL(4);
#if OSD_ENABLE_SCREENSPACE_TESSELLATION
#ifdef OSD_ENABLE_SCREENSPACE_TESSELLATION
gl_TessLevelOuter[0] =
TessAdaptive(input[0].v.hullPosition.xyz, input[1].v.hullPosition.xyz, patchLevel);
TessAdaptive(inpt[0].v.hullPosition.xyz, inpt[1].v.hullPosition.xyz, patchLevel);
gl_TessLevelOuter[1] =
TessAdaptive(input[0].v.hullPosition.xyz, input[3].v.hullPosition.xyz, patchLevel);
TessAdaptive(inpt[0].v.hullPosition.xyz, inpt[3].v.hullPosition.xyz, patchLevel);
gl_TessLevelOuter[2] =
TessAdaptive(input[2].v.hullPosition.xyz, input[3].v.hullPosition.xyz, patchLevel);
TessAdaptive(inpt[2].v.hullPosition.xyz, inpt[3].v.hullPosition.xyz, patchLevel);
gl_TessLevelOuter[3] =
TessAdaptive(input[1].v.hullPosition.xyz, input[2].v.hullPosition.xyz, patchLevel);
TessAdaptive(inpt[1].v.hullPosition.xyz, inpt[2].v.hullPosition.xyz, patchLevel);
gl_TessLevelInner[0] =
max(gl_TessLevelOuter[1], gl_TessLevelOuter[3]);
gl_TessLevelInner[1] =
@ -444,11 +443,11 @@ layout(cw) in;
in block {
GregEvalVertex v;
} input[];
} inpt[];
out block {
OutputVertex v;
} output;
} outpt;
void main()
{
@ -457,29 +456,29 @@ void main()
vec3 p[20];
p[0] = input[0].v.position;
p[1] = input[0].v.Ep;
p[2] = input[0].v.Em;
p[3] = input[0].v.Fp;
p[4] = input[0].v.Fm;
p[0] = inpt[0].v.position;
p[1] = inpt[0].v.Ep;
p[2] = inpt[0].v.Em;
p[3] = inpt[0].v.Fp;
p[4] = inpt[0].v.Fm;
p[5] = input[1].v.position;
p[6] = input[1].v.Ep;
p[7] = input[1].v.Em;
p[8] = input[1].v.Fp;
p[9] = input[1].v.Fm;
p[5] = inpt[1].v.position;
p[6] = inpt[1].v.Ep;
p[7] = inpt[1].v.Em;
p[8] = inpt[1].v.Fp;
p[9] = inpt[1].v.Fm;
p[10] = input[2].v.position;
p[11] = input[2].v.Ep;
p[12] = input[2].v.Em;
p[13] = input[2].v.Fp;
p[14] = input[2].v.Fm;
p[10] = inpt[2].v.position;
p[11] = inpt[2].v.Ep;
p[12] = inpt[2].v.Em;
p[13] = inpt[2].v.Fp;
p[14] = inpt[2].v.Fm;
p[15] = input[3].v.position;
p[16] = input[3].v.Ep;
p[17] = input[3].v.Em;
p[18] = input[3].v.Fp;
p[19] = input[3].v.Fm;
p[15] = inpt[3].v.position;
p[16] = inpt[3].v.Ep;
p[17] = inpt[3].v.Em;
p[18] = inpt[3].v.Fp;
p[19] = inpt[3].v.Fm;
vec3 q[16];
@ -543,11 +542,11 @@ void main()
vec3 normal = normalize(cross(BiTangent, Tangent));
output.v.position = ModelViewMatrix * vec4(WorldPos, 1.0f);
output.v.normal = normal;
output.v.patchCoord = input[0].v.patchCoord;
output.v.patchCoord.xy = vec2(v, u);
output.v.tangent = normalize(BiTangent);
outpt.v.position = ModelViewMatrix * vec4(WorldPos, 1.0f);
outpt.v.normal = normal;
outpt.v.patchCoord = inpt[0].v.patchCoord;
outpt.v.patchCoord.xy = vec2(v, u);
outpt.v.tangent = normalize(BiTangent);
OSD_COMPUTE_PTEX_COORD_TESSEVAL_SHADER;
@ -569,11 +568,11 @@ layout (location=2) in vec4 color;
out block {
OutputVertex v;
} output;
} outpt;
void main() {
gl_Position = ModelViewProjectionMatrix * position;
output.v.color = color;
outpt.v.color = color;
}
#endif
@ -585,9 +584,9 @@ void main() {
in block {
OutputVertex v;
} input;
} inpt;
void main() {
gl_FragColor = input.v.color;
gl_FragColor = inpt.v.color;
}
#endif

View File

@ -55,8 +55,6 @@
// a particular purpose and non-infringement.
//
#extension GL_EXT_gpu_shader4 : require
//----------------------------------------------------------
// Patches.Common
//----------------------------------------------------------
@ -65,6 +63,10 @@
#define OSD_NUM_VARYINGS 0
#endif
#ifndef ROTATE
#define ROTATE 0
#endif
#define M_PI 3.14159265359f
struct ControlVertex {
@ -82,7 +84,7 @@ struct OutputVertex {
vec3 normal;
vec3 tangent;
centroid vec4 patchCoord; // u, v, level, faceID
noperspective vec4 edgeDistance;
centroid vec2 tessCoord; // tesscoord.st
#if OSD_NUM_VARYINGS > 0
float varyings[OSD_NUM_VARYINGS];
#endif
@ -136,7 +138,7 @@ uniform int LevelBase;
float GetTessLevel(int patchLevel)
{
#if OSD_ENABLE_SCREENSPACE_TESSELLATION
#ifdef OSD_ENABLE_SCREENSPACE_TESSELLATION
return TessLevel;
#else
return TessLevel / pow(2, patchLevel-1);
@ -165,50 +167,47 @@ float TessAdaptive(vec3 p0, vec3 p1, int patchLevel)
uniform isamplerBuffer g_ptexIndicesBuffer;
int GetPatchLevel()
{
ivec2 ptexIndex = texelFetchBuffer(g_ptexIndicesBuffer,
gl_PrimitiveID + LevelBase).xy;
return (ptexIndex.y & 0xf);
}
#define GetPatchLevel() \
(texelFetch(g_ptexIndicesBuffer, gl_PrimitiveID + LevelBase).y & 0xf)
#define OSD_COMPUTE_PTEX_COORD_TESSCONTROL_SHADER \
{ \
ivec2 ptexIndex = texelFetchBuffer(g_ptexIndicesBuffer, \
gl_PrimitiveID + LevelBase).xy; \
ivec2 ptexIndex = texelFetch(g_ptexIndicesBuffer, \
gl_PrimitiveID + LevelBase).xy; \
int faceID = ptexIndex.x; \
int lv = 1 << (ptexIndex.y & 0xf); \
int u = (ptexIndex.y >> 17) & 0x3ff; \
int v = (ptexIndex.y >> 7) & 0x3ff; \
int rotation = (ptexIndex.y >> 5) & 0x3; \
output[ID].v.patchCoord.w = faceID+0.5; \
output[ID].v.ptexInfo = ivec4(u, v, lv, rotation); \
outpt[ID].v.patchCoord.w = faceID+0.5; \
outpt[ID].v.ptexInfo = ivec4(u, v, lv, rotation); \
}
#define OSD_COMPUTE_PTEX_COORD_TESSEVAL_SHADER \
{ \
vec2 uv = output.v.patchCoord.xy; \
ivec2 p = input[0].v.ptexInfo.xy; \
int lv = input[0].v.ptexInfo.z; \
int rot = input[0].v.ptexInfo.w; \
vec2 uv = outpt.v.patchCoord.xy; \
ivec2 p = inpt[0].v.ptexInfo.xy; \
int lv = inpt[0].v.ptexInfo.z; \
int rot = inpt[0].v.ptexInfo.w; \
outpt.v.tessCoord.xy = uv; \
uv.xy = float(rot==0)*uv.xy \
+ float(rot==1)*vec2(1.0-uv.y, uv.x) \
+ float(rot==2)*vec2(1.0-uv.x, 1.0-uv.y) \
+ float(rot==3)*vec2(uv.y, 1.0-uv.x); \
output.v.patchCoord.xy = (uv * vec2(1.0)/lv) + vec2(p.x, p.y)/lv; \
outpt.v.patchCoord.xy = (uv * vec2(1.0)/lv) + vec2(p.x, p.y)/lv; \
}
#define OSD_COMPUTE_PTEX_COMPATIBLE_TANGENT(ROTATE) \
{ \
int rot = (input[0].v.ptexInfo.w + 4 - ROTATE)%4; \
int rot = (inpt[0].v.ptexInfo.w + 4 - ROTATE)%4; \
if (rot == 1) { \
output.v.tangent = -normalize(Tangent); \
outpt.v.tangent = -normalize(Tangent); \
} else if (rot == 2) { \
output.v.tangent = -normalize(BiTangent); \
outpt.v.tangent = -normalize(BiTangent); \
} else if (rot == 3) { \
output.v.tangent = normalize(Tangent); \
outpt.v.tangent = normalize(Tangent); \
} else { \
output.v.tangent = normalize(BiTangent); \
outpt.v.tangent = normalize(BiTangent); \
} \
}
@ -218,12 +217,12 @@ int GetPatchLevel()
vec4 clipPos = ModelViewProjectionMatrix * P; \
bvec3 clip0 = lessThan(clipPos.xyz, vec3(clipPos.w)); \
bvec3 clip1 = greaterThan(clipPos.xyz, -vec3(clipPos.w)); \
output.v.clipFlag = ivec3(clip0) + 2*ivec3(clip1); \
outpt.v.clipFlag = ivec3(clip0) + 2*ivec3(clip1); \
#define OSD_PATCH_CULL(N) \
ivec3 clipFlag = ivec3(0); \
for(int i = 0; i < N; ++i) { \
clipFlag |= input[i].v.clipFlag; \
clipFlag |= inpt[i].v.clipFlag; \
} \
if (clipFlag != ivec3(3) ) { \
gl_TessLevelInner[0] = 0; \
@ -270,12 +269,12 @@ uniform mat4 R = mat4(
);
#if OSD_MAX_VALENCE<=10
uniform float ef[7] = {
uniform float ef[7] = float[](
0.813008, 0.500000, 0.363636, 0.287505,
0.238692, 0.204549, 0.179211
};
);
#else
uniform float ef[27] = {
uniform float ef[27] = float[](
0.812816, 0.500000, 0.363644, 0.287514,
0.238688, 0.204544, 0.179229, 0.159657,
0.144042, 0.131276, 0.120632, 0.111614,
@ -283,7 +282,7 @@ uniform float ef[27] = {
0.0814022, 0.0772401, 0.0734867, 0.0700842,
0.0669851, 0.0641504, 0.0615475, 0.0591488,
0.0569311, 0.0548745, 0.0529621
};
);
#endif
float csf(uint n, uint j)

View File

@ -55,7 +55,6 @@
// a particular purpose and non-infringement.
//
#extension GL_EXT_gpu_shader4 : require
//----------------------------------------------------------
// Patches.TessVertex
//----------------------------------------------------------
@ -65,15 +64,15 @@ layout (location=0) in vec4 position;
out block {
ControlVertex v;
} output;
} outpt;
void main() {
output.v.position = ModelViewMatrix * position;
outpt.v.position = ModelViewMatrix * position;
OSD_PATCH_CULL_COMPUTE_CLIPFLAGS(position);
#if OSD_NUM_VARYINGS > 0
for (int i = 0; i < OSD_NUM_VARYINGS; ++i)
output.v.varyings[i] = varyings[i];
outpt.v.varyings[i] = varyings[i];
#endif
}
@ -88,11 +87,11 @@ layout(vertices = 16) out;
in block {
ControlVertex v;
} input[];
} inpt[];
out block {
ControlVertex v;
} output[];
} outpt[];
#define ID gl_InvocationID
@ -106,7 +105,7 @@ void main()
H[l] = vec3(0,0,0);
for (int k=0; k<3; k++) {
float c = B[i][2-k];
H[l] += c*input[l*3 + k].v.position.xyz;
H[l] += c*inpt[l*3 + k].v.position.xyz;
}
}
@ -115,31 +114,31 @@ void main()
pos += B[j][k]*H[k];
}
output[ID].v.position = vec4(pos, 1.0);
outpt[ID].v.position = vec4(pos, 1.0);
int patchLevel = GetPatchLevel();
// +0.5 to avoid interpolation error of integer value
output[ID].v.patchCoord = vec4(0, 0,
patchLevel+0.5,
gl_PrimitiveID+LevelBase+0.5);
outpt[ID].v.patchCoord = vec4(0, 0,
patchLevel+0.5,
gl_PrimitiveID+LevelBase+0.5);
OSD_COMPUTE_PTEX_COORD_TESSCONTROL_SHADER;
if (ID == 0) {
OSD_PATCH_CULL(9);
#if OSD_ENABLE_SCREENSPACE_TESSELLATION
#ifdef OSD_ENABLE_SCREENSPACE_TESSELLATION
gl_TessLevelOuter[0] =
TessAdaptive(input[2].v.position.xyz, input[5].v.position.xyz, patchLevel);
TessAdaptive(inpt[2].v.position.xyz, inpt[5].v.position.xyz, patchLevel);
gl_TessLevelOuter[1] =
TessAdaptive(input[1].v.position.xyz, input[2].v.position.xyz, patchLevel);
TessAdaptive(inpt[1].v.position.xyz, inpt[2].v.position.xyz, patchLevel);
gl_TessLevelOuter[2] =
TessAdaptive(input[4].v.position.xyz, input[5].v.position.xyz, patchLevel);
TessAdaptive(inpt[4].v.position.xyz, inpt[5].v.position.xyz, patchLevel);
gl_TessLevelOuter[3] =
TessAdaptive(input[1].v.position.xyz, input[4].v.position.xyz, patchLevel);
TessAdaptive(inpt[1].v.position.xyz, inpt[4].v.position.xyz, patchLevel);
gl_TessLevelInner[0] =
max(gl_TessLevelOuter[1], gl_TessLevelOuter[3]);
@ -168,11 +167,11 @@ layout(equal_spacing) in;
in block {
ControlVertex v;
} input[];
} inpt[];
out block {
OutputVertex v;
} output;
} outpt;
void main()
{
@ -190,7 +189,7 @@ void main()
DUCP[i] = vec3(0.0f, 0.0f, 0.0f);
for (int j=0; j<4; ++j) {
vec3 A = input[4*i + j].v.position.xyz;
vec3 A = inpt[4*i + j].v.position.xyz;
BUCP[i] += A * B[j];
DUCP[i] += A * D[j];
@ -211,14 +210,14 @@ void main()
vec3 normal = normalize(cross(Tangent, BiTangent));
output.v.position = vec4(WorldPos, 1.0f);
output.v.normal = normal;
outpt.v.position = vec4(WorldPos, 1.0f);
outpt.v.normal = normal;
BiTangent = -BiTangent; // BiTangent will be used in following macro
output.v.tangent = BiTangent;
outpt.v.tangent = BiTangent;
output.v.patchCoord = input[0].v.patchCoord;
output.v.patchCoord.xy = vec2(1.0-v, u);
outpt.v.patchCoord = inpt[0].v.patchCoord;
outpt.v.patchCoord.xy = vec2(1.0-v, u);
OSD_COMPUTE_PTEX_COORD_TESSEVAL_SHADER;
@ -242,11 +241,11 @@ layout (location=2) in vec4 color;
out block {
OutputVertex v;
} output;
} outpt;
void main() {
gl_Position = ModelViewProjectionMatrix * position;
output.v.color = color;
outpt.v.color = color;
}
#endif
@ -258,9 +257,9 @@ void main() {
in block {
OutputVertex v;
} input;
} inpt;
void main() {
gl_FragColor = input.v.color;
gl_FragColor = inpt.v.color;
}
#endif

View File

@ -55,7 +55,6 @@
// a particular purpose and non-infringement.
//
#extension GL_EXT_gpu_shader4 : require
//----------------------------------------------------------
// Patches.TessVertexGregory
//----------------------------------------------------------
@ -68,17 +67,17 @@ layout (location=0) in vec4 position;
out block {
GregControlVertex v;
} output;
} outpt;
void main()
{
int vID = gl_VertexID;
output.v.hullPosition = (ModelViewMatrix * position).xyz;
outpt.v.hullPosition = (ModelViewMatrix * position).xyz;
OSD_PATCH_CULL_COMPUTE_CLIPFLAGS(position);
uint valence = uint(texelFetchBuffer(g_ValenceBuffer,int(vID * (2 * OSD_MAX_VALENCE + 1))).x);
output.v.valence = int(valence);
uint valence = uint(texelFetch(g_ValenceBuffer,int(vID * (2 * OSD_MAX_VALENCE + 1))).x);
outpt.v.valence = int(valence);
vec3 f[OSD_MAX_VALENCE];
vec3 pos = position.xyz;
@ -88,66 +87,66 @@ void main()
uint im=(i+valence-1)%valence;
uint ip=(i+1)%valence;
uint idx_neighbor = uint(texelFetchBuffer(g_ValenceBuffer, int(vID * (2*OSD_MAX_VALENCE+1) + 2*i + 0 + 1)).x);
uint idx_neighbor = uint(texelFetch(g_ValenceBuffer, int(vID * (2*OSD_MAX_VALENCE+1) + 2*i + 0 + 1)).x);
vec3 neighbor =
vec3(texelFetchBuffer(g_VertexBuffer, int(OSD_NUM_ELEMENTS*idx_neighbor)).x,
texelFetchBuffer(g_VertexBuffer, int(OSD_NUM_ELEMENTS*idx_neighbor+1)).x,
texelFetchBuffer(g_VertexBuffer, int(OSD_NUM_ELEMENTS*idx_neighbor+2)).x);
vec3(texelFetch(g_VertexBuffer, int(OSD_NUM_ELEMENTS*idx_neighbor)).x,
texelFetch(g_VertexBuffer, int(OSD_NUM_ELEMENTS*idx_neighbor+1)).x,
texelFetch(g_VertexBuffer, int(OSD_NUM_ELEMENTS*idx_neighbor+2)).x);
uint idx_diagonal = uint(texelFetchBuffer(g_ValenceBuffer, int(vID * (2*OSD_MAX_VALENCE+1) + 2*i + 1 + 1)).x);
uint idx_diagonal = uint(texelFetch(g_ValenceBuffer, int(vID * (2*OSD_MAX_VALENCE+1) + 2*i + 1 + 1)).x);
vec3 diagonal =
vec3(texelFetchBuffer(g_VertexBuffer, int(OSD_NUM_ELEMENTS*idx_diagonal)).x,
texelFetchBuffer(g_VertexBuffer, int(OSD_NUM_ELEMENTS*idx_diagonal+1)).x,
texelFetchBuffer(g_VertexBuffer, int(OSD_NUM_ELEMENTS*idx_diagonal+2)).x);
vec3(texelFetch(g_VertexBuffer, int(OSD_NUM_ELEMENTS*idx_diagonal)).x,
texelFetch(g_VertexBuffer, int(OSD_NUM_ELEMENTS*idx_diagonal+1)).x,
texelFetch(g_VertexBuffer, int(OSD_NUM_ELEMENTS*idx_diagonal+2)).x);
uint idx_neighbor_p = uint(texelFetchBuffer(g_ValenceBuffer, int(vID * (2*OSD_MAX_VALENCE+1) + 2*ip + 0 + 1)).x);
uint idx_neighbor_p = uint(texelFetch(g_ValenceBuffer, int(vID * (2*OSD_MAX_VALENCE+1) + 2*ip + 0 + 1)).x);
vec3 neighbor_p =
vec3(texelFetchBuffer(g_VertexBuffer, int(OSD_NUM_ELEMENTS*idx_neighbor_p)).x,
texelFetchBuffer(g_VertexBuffer, int(OSD_NUM_ELEMENTS*idx_neighbor_p+1)).x,
texelFetchBuffer(g_VertexBuffer, int(OSD_NUM_ELEMENTS*idx_neighbor_p+2)).x);
vec3(texelFetch(g_VertexBuffer, int(OSD_NUM_ELEMENTS*idx_neighbor_p)).x,
texelFetch(g_VertexBuffer, int(OSD_NUM_ELEMENTS*idx_neighbor_p+1)).x,
texelFetch(g_VertexBuffer, int(OSD_NUM_ELEMENTS*idx_neighbor_p+2)).x);
uint idx_neighbor_m = uint(texelFetchBuffer(g_ValenceBuffer, int(vID * (2*OSD_MAX_VALENCE+1) + 2*im + 0 + 1)).x);
uint idx_neighbor_m = uint(texelFetch(g_ValenceBuffer, int(vID * (2*OSD_MAX_VALENCE+1) + 2*im + 0 + 1)).x);
vec3 neighbor_m =
vec3(texelFetchBuffer(g_VertexBuffer, int(OSD_NUM_ELEMENTS*idx_neighbor_m)).x,
texelFetchBuffer(g_VertexBuffer, int(OSD_NUM_ELEMENTS*idx_neighbor_m+1)).x,
texelFetchBuffer(g_VertexBuffer, int(OSD_NUM_ELEMENTS*idx_neighbor_m+2)).x);
vec3(texelFetch(g_VertexBuffer, int(OSD_NUM_ELEMENTS*idx_neighbor_m)).x,
texelFetch(g_VertexBuffer, int(OSD_NUM_ELEMENTS*idx_neighbor_m+1)).x,
texelFetch(g_VertexBuffer, int(OSD_NUM_ELEMENTS*idx_neighbor_m+2)).x);
uint idx_diagonal_m = uint(texelFetchBuffer(g_ValenceBuffer, int(vID * (2*OSD_MAX_VALENCE+1) + 2*im + 1 + 1)).x);
uint idx_diagonal_m = uint(texelFetch(g_ValenceBuffer, int(vID * (2*OSD_MAX_VALENCE+1) + 2*im + 1 + 1)).x);
vec3 diagonal_m =
vec3(texelFetchBuffer(g_VertexBuffer, int(OSD_NUM_ELEMENTS*idx_diagonal_m)).x,
texelFetchBuffer(g_VertexBuffer, int(OSD_NUM_ELEMENTS*idx_diagonal_m+1)).x,
texelFetchBuffer(g_VertexBuffer, int(OSD_NUM_ELEMENTS*idx_diagonal_m+2)).x);
vec3(texelFetch(g_VertexBuffer, int(OSD_NUM_ELEMENTS*idx_diagonal_m)).x,
texelFetch(g_VertexBuffer, int(OSD_NUM_ELEMENTS*idx_diagonal_m+1)).x,
texelFetch(g_VertexBuffer, int(OSD_NUM_ELEMENTS*idx_diagonal_m+2)).x);
f[i] = (pos * float(valence) + (neighbor_p + neighbor)*2.0 + diagonal) / (float(valence)+5.0);
opos += f[i];
output.v.r[i] = (neighbor_p-neighbor_m)/3.0 + (diagonal - diagonal_m)/6.0;
outpt.v.r[i] = (neighbor_p-neighbor_m)/3.0 + (diagonal - diagonal_m)/6.0;
}
opos /= valence;
output.v.position = vec4(opos, 1.0f).xyz;
outpt.v.position = vec4(opos, 1.0f).xyz;
#if OSD_NUM_VARYINGS > 0
for (int i = 0; i < OSD_NUM_VARYINGS; ++i)
output.v.varyings[i] = varyings[i];
outpt.v.varyings[i] = varyings[i];
#endif
vec3 e;
output.v.e0 = vec3(0,0,0);
output.v.e1 = vec3(0,0,0);
outpt.v.e0 = vec3(0,0,0);
outpt.v.e1 = vec3(0,0,0);
for(uint i=0; i<valence; ++i) {
uint im = (i + valence -1) % valence;
e = 0.5 * (f[i] + f[im]);
output.v.e0 += csf(valence-3, 2*i) *e;
output.v.e1 += csf(valence-3, 2*i + 1)*e;
outpt.v.e0 += csf(valence-3, 2*i) *e;
outpt.v.e1 += csf(valence-3, 2*i + 1)*e;
}
output.v.e0 *= ef[valence - 3];
output.v.e1 *= ef[valence - 3];
outpt.v.e0 *= ef[valence - 3];
outpt.v.e1 *= ef[valence - 3];
}
#endif
@ -162,11 +161,11 @@ uniform isamplerBuffer g_QuadOffsetBuffer;
in block {
GregControlVertex v;
} input[];
} inpt[];
out block {
GregEvalVertex v;
} output[];
} outpt[];
#define ID gl_InvocationID
@ -175,13 +174,13 @@ void main()
uint i = gl_InvocationID;
uint ip = (i+1)%4;
uint im = (i+3)%4;
uint n = uint(input[i].v.valence);
uint n = uint(inpt[i].v.valence);
int base = GregoryQuadOffsetBase;
output[ID].v.position = input[ID].v.position;
outpt[ID].v.position = inpt[ID].v.position;
uint start = texelFetchBuffer(g_QuadOffsetBuffer, int(4*gl_PrimitiveID+base + i)).x & 0x00ff;
uint prev = uint(texelFetchBuffer(g_QuadOffsetBuffer, int(4*gl_PrimitiveID+base + i)).x) & 0xff00;
uint start = uint(texelFetch(g_QuadOffsetBuffer, int(4*gl_PrimitiveID+base + i)).x) & 0x00ffu;
uint prev = uint(texelFetch(g_QuadOffsetBuffer, int(4*gl_PrimitiveID+base + i)).x) & 0xff00u;
prev=uint(prev/256);
// Control Vertices based on :
@ -208,51 +207,51 @@ void main()
// P0 e0+ e1- E1
//
vec3 Ep = input[i].v.position + input[i].v.e0 * csf(n-3, 2*start) + input[i].v.e1*csf(n-3, 2*start +1);
vec3 Em = input[i].v.position + input[i].v.e0 * csf(n-3, 2*prev ) + input[i].v.e1*csf(n-3, 2*prev + 1);
vec3 Ep = inpt[i].v.position + inpt[i].v.e0 * csf(n-3, 2*start) + inpt[i].v.e1*csf(n-3, 2*start +1);
vec3 Em = inpt[i].v.position + inpt[i].v.e0 * csf(n-3, 2*prev ) + inpt[i].v.e1*csf(n-3, 2*prev + 1);
uint np = input[ip].v.valence;
uint nm = input[im].v.valence;
uint np = inpt[ip].v.valence;
uint nm = inpt[im].v.valence;
uint prev_p = uint(texelFetchBuffer(g_QuadOffsetBuffer, int(4*gl_PrimitiveID+base + ip)).x)&0xff00;
uint prev_p = uint(texelFetch(g_QuadOffsetBuffer, int(4*gl_PrimitiveID+base + ip)).x) & 0xff00u;
prev_p=uint(prev_p/256);
vec3 Em_ip = input[ip].v.position + input[ip].v.e0*csf(np-3,2*prev_p) +input[ip].v.e1*csf(np-3, 2*prev_p+1);
vec3 Em_ip = inpt[ip].v.position + inpt[ip].v.e0*csf(np-3,2*prev_p) +inpt[ip].v.e1*csf(np-3, 2*prev_p+1);
uint start_m = texelFetchBuffer(g_QuadOffsetBuffer, int(4*gl_PrimitiveID+base + im)).x&0x00ff;
vec3 Ep_im = input[im].v.position + input[im].v.e0*csf(nm-3, 2*start_m) + input[im].v.e1*csf(nm-3, 2*start_m+1);
uint start_m = uint(texelFetch(g_QuadOffsetBuffer, int(4*gl_PrimitiveID+base + im)).x) & 0x00ffu;
vec3 Ep_im = inpt[im].v.position + inpt[im].v.e0*csf(nm-3, 2*start_m) + inpt[im].v.e1*csf(nm-3, 2*start_m+1);
float s1 = 3 - 2*csf(n-3,2)-csf(np-3,2);
float s2 = 2*csf(n-3,2);
vec3 Fp = (csf(np-3,2)*input[i].v.position + s1*Ep + s2*Em_ip + input[i].v.r[start])/3.0;
vec3 Fp = (csf(np-3,2)*inpt[i].v.position + s1*Ep + s2*Em_ip + inpt[i].v.r[start])/3.0;
s1 = 3.0 -2.0*cos(2.0*M_PI/float(n)) - cos(2*M_PI/float(nm));
vec3 Fm = (csf(nm-3,2)*input[i].v.position + s1*Em +s2*Ep_im - input[i].v.r[prev])/3.0;
vec3 Fm = (csf(nm-3,2)*inpt[i].v.position + s1*Em +s2*Ep_im - inpt[i].v.r[prev])/3.0;
output[ID].v.Ep = Ep;
output[ID].v.Em = Em;
output[ID].v.Fp = Fp;
output[ID].v.Fm = Fm;
outpt[ID].v.Ep = Ep;
outpt[ID].v.Em = Em;
outpt[ID].v.Fp = Fp;
outpt[ID].v.Fm = Fm;
int patchLevel = GetPatchLevel();
output[ID].v.patchCoord = vec4(0, 0,
patchLevel+0.5,
gl_PrimitiveID+LevelBase+0.5);
outpt[ID].v.patchCoord = vec4(0, 0,
patchLevel+0.5,
gl_PrimitiveID+LevelBase+0.5);
OSD_COMPUTE_PTEX_COORD_TESSCONTROL_SHADER;
if (ID == 0) {
OSD_PATCH_CULL(4);
#if OSD_ENABLE_SCREENSPACE_TESSELLATION
#ifdef OSD_ENABLE_SCREENSPACE_TESSELLATION
gl_TessLevelOuter[0] =
TessAdaptive(input[0].v.hullPosition.xyz, input[1].v.hullPosition.xyz, patchLevel);
TessAdaptive(inpt[0].v.hullPosition.xyz, inpt[1].v.hullPosition.xyz, patchLevel);
gl_TessLevelOuter[1] =
TessAdaptive(input[0].v.hullPosition.xyz, input[3].v.hullPosition.xyz, patchLevel);
TessAdaptive(inpt[0].v.hullPosition.xyz, inpt[3].v.hullPosition.xyz, patchLevel);
gl_TessLevelOuter[2] =
TessAdaptive(input[2].v.hullPosition.xyz, input[3].v.hullPosition.xyz, patchLevel);
TessAdaptive(inpt[2].v.hullPosition.xyz, inpt[3].v.hullPosition.xyz, patchLevel);
gl_TessLevelOuter[3] =
TessAdaptive(input[1].v.hullPosition.xyz, input[2].v.hullPosition.xyz, patchLevel);
TessAdaptive(inpt[1].v.hullPosition.xyz, inpt[2].v.hullPosition.xyz, patchLevel);
gl_TessLevelInner[0] =
max(gl_TessLevelOuter[1], gl_TessLevelOuter[3]);
gl_TessLevelInner[1] =
@ -279,11 +278,11 @@ layout(cw) in;
in block {
GregEvalVertex v;
} input[];
} inpt[];
out block {
OutputVertex v;
} output;
} outpt;
void main()
{
@ -292,29 +291,29 @@ void main()
vec3 p[20];
p[0] = input[0].v.position;
p[1] = input[0].v.Ep;
p[2] = input[0].v.Em;
p[3] = input[0].v.Fp;
p[4] = input[0].v.Fm;
p[0] = inpt[0].v.position;
p[1] = inpt[0].v.Ep;
p[2] = inpt[0].v.Em;
p[3] = inpt[0].v.Fp;
p[4] = inpt[0].v.Fm;
p[5] = input[1].v.position;
p[6] = input[1].v.Ep;
p[7] = input[1].v.Em;
p[8] = input[1].v.Fp;
p[9] = input[1].v.Fm;
p[5] = inpt[1].v.position;
p[6] = inpt[1].v.Ep;
p[7] = inpt[1].v.Em;
p[8] = inpt[1].v.Fp;
p[9] = inpt[1].v.Fm;
p[10] = input[2].v.position;
p[11] = input[2].v.Ep;
p[12] = input[2].v.Em;
p[13] = input[2].v.Fp;
p[14] = input[2].v.Fm;
p[10] = inpt[2].v.position;
p[11] = inpt[2].v.Ep;
p[12] = inpt[2].v.Em;
p[13] = inpt[2].v.Fp;
p[14] = inpt[2].v.Fm;
p[15] = input[3].v.position;
p[16] = input[3].v.Ep;
p[17] = input[3].v.Em;
p[18] = input[3].v.Fp;
p[19] = input[3].v.Fm;
p[15] = inpt[3].v.position;
p[16] = inpt[3].v.Ep;
p[17] = inpt[3].v.Em;
p[18] = inpt[3].v.Fp;
p[19] = inpt[3].v.Fm;
vec3 q[16];
@ -378,18 +377,18 @@ void main()
vec3 normal = normalize(cross(BiTangent, Tangent));
output.v.position = ModelViewMatrix * vec4(WorldPos, 1.0);
output.v.normal = normal;
output.v.tangent = BiTangent;
outpt.v.position = ModelViewMatrix * vec4(WorldPos, 1.0);
outpt.v.normal = normal;
outpt.v.tangent = BiTangent;
output.v.patchCoord = input[0].v.patchCoord;
output.v.patchCoord.xy = vec2(v, u);
outpt.v.patchCoord = inpt[0].v.patchCoord;
outpt.v.patchCoord.xy = vec2(v, u);
OSD_COMPUTE_PTEX_COORD_TESSEVAL_SHADER;
OSD_DISPLACEMENT_CALLBACK;
gl_Position = ProjectionMatrix * output.v.position;
gl_Position = ProjectionMatrix * outpt.v.position;
}
#endif
@ -405,11 +404,11 @@ layout (location=2) in vec4 color;
out block {
OutputVertex v;
} output;
} outpt;
void main() {
gl_Position = ModelViewProjectionMatrix * position;
output.v.color = color;
outpt.v.color = color;
}
#endif
@ -421,9 +420,9 @@ void main() {
in block {
OutputVertex v;
} input;
} inpt;
void main() {
gl_FragColor = input.v.color;
gl_FragColor = inpt.v.color;
}
#endif

View File

@ -55,9 +55,6 @@
// a particular purpose and non-infringement.
//
#extension GL_EXT_gpu_shader4 : require
#line 2
//----------------------------------------------------------
// Patches.TessVertex
//----------------------------------------------------------
@ -67,15 +64,15 @@ layout (location=0) in vec4 position;
out block {
ControlVertex v;
} output;
} outpt;
void main() {
output.v.position = ModelViewMatrix * position;
outpt.v.position = ModelViewMatrix * position;
OSD_PATCH_CULL_COMPUTE_CLIPFLAGS(position);
#if OSD_NUM_VARYINGS > 0
for (int i = 0; i < OSD_NUM_VARYINGS; ++i)
output.v.varyings[i] = varyings[i];
outpt.v.varyings[i] = varyings[i];
#endif
}
@ -90,11 +87,11 @@ layout(vertices = 16) out;
in block {
ControlVertex v;
} input[];
} inpt[];
out block {
ControlVertex v;
} output[];
} outpt[];
#define ID gl_InvocationID
@ -109,8 +106,8 @@ void main()
for (int k=0; k<4; k++) {
float c = Q[i][k];
// XXX: fix this in patchMeshFactory.
// H[l] += c*input[l*4 + k].v.position.xyz;
H[l] += c*input[l + k*4].v.position.xyz;
// H[l] += c*inpt[l*4 + k].v.position.xyz;
H[l] += c*inpt[l + k*4].v.position.xyz;
}
}
@ -119,29 +116,29 @@ void main()
pos += Q[j][k]*H[k];
}
output[ID].v.position = vec4(pos, 1.0);
outpt[ID].v.position = vec4(pos, 1.0);
int patchLevel = GetPatchLevel();
// +0.5 to avoid interpolation error of integer value
output[ID].v.patchCoord = vec4(0, 0,
patchLevel+0.5,
gl_PrimitiveID+LevelBase+0.5);
outpt[ID].v.patchCoord = vec4(0, 0,
patchLevel+0.5,
gl_PrimitiveID+LevelBase+0.5);
OSD_COMPUTE_PTEX_COORD_TESSCONTROL_SHADER;
if (ID == 0) {
OSD_PATCH_CULL(16);
#if OSD_ENABLE_SCREENSPACE_TESSELLATION
#ifdef OSD_ENABLE_SCREENSPACE_TESSELLATION
gl_TessLevelOuter[0] =
TessAdaptive(input[5].v.position.xyz, input[9].v.position.xyz, patchLevel);
TessAdaptive(inpt[5].v.position.xyz, inpt[9].v.position.xyz, patchLevel);
gl_TessLevelOuter[1] =
TessAdaptive(input[5].v.position.xyz, input[6].v.position.xyz, patchLevel);
TessAdaptive(inpt[5].v.position.xyz, inpt[6].v.position.xyz, patchLevel);
gl_TessLevelOuter[2] =
TessAdaptive(input[6].v.position.xyz, input[10].v.position.xyz, patchLevel);
TessAdaptive(inpt[6].v.position.xyz, inpt[10].v.position.xyz, patchLevel);
gl_TessLevelOuter[3] =
TessAdaptive(input[9].v.position.xyz, input[10].v.position.xyz, patchLevel);
TessAdaptive(inpt[9].v.position.xyz, inpt[10].v.position.xyz, patchLevel);
gl_TessLevelInner[0] =
max(gl_TessLevelOuter[1], gl_TessLevelOuter[3]);
gl_TessLevelInner[1] =
@ -169,11 +166,11 @@ layout(equal_spacing) in;
in block {
ControlVertex v;
} input[];
} inpt[];
out block {
OutputVertex v;
} output;
} outpt;
void main()
{
@ -182,17 +179,17 @@ void main()
vec3 WorldPos, Tangent, BiTangent;
vec3 cp[16];
for(int i = 0; i < 16; ++i) cp[i] = input[i].v.position.xyz;
for(int i = 0; i < 16; ++i) cp[i] = inpt[i].v.position.xyz;
EvalBSpline(gl_TessCoord.xy, cp, WorldPos, Tangent, BiTangent);
vec3 normal = normalize(cross(Tangent, BiTangent));
output.v.position = vec4(WorldPos, 1.0f);
output.v.normal = normal;
output.v.tangent = Tangent;
outpt.v.position = vec4(WorldPos, 1.0f);
outpt.v.normal = normal;
outpt.v.tangent = Tangent;
output.v.patchCoord = input[0].v.patchCoord;
output.v.patchCoord.xy = vec2(u, v);
outpt.v.patchCoord = inpt[0].v.patchCoord;
outpt.v.patchCoord.xy = vec2(u, v);
OSD_COMPUTE_PTEX_COORD_TESSEVAL_SHADER;
@ -214,11 +211,11 @@ layout (location=2) in vec4 color;
out block {
OutputVertex v;
} output;
} outpt;
void main() {
gl_Position = ModelViewProjectionMatrix * position;
output.v.color = color;
outpt.v.color = color;
}
#endif
@ -230,9 +227,9 @@ void main() {
in block {
OutputVertex v;
} input;
} inpt;
void main() {
gl_FragColor = input.v.color;
gl_FragColor = inpt.v.color;
}
#endif

View File

@ -55,9 +55,6 @@
// a particular purpose and non-infringement.
//
#extension GL_EXT_gpu_shader4 : require
#line 2
//----------------------------------------------------------
// Patches.Coefficients
//----------------------------------------------------------
@ -81,15 +78,15 @@ layout (location=0) in vec4 position;
out block {
ControlVertex v;
} output;
} outpt;
void main() {
output.v.position = ModelViewMatrix * position;
outpt.v.position = ModelViewMatrix * position;
OSD_PATCH_CULL_COMPUTE_CLIPFLAGS(position);
#if OSD_NUM_VARYINGS > 0
for (int i = 0; i < OSD_NUM_VARYINGS; ++i)
output.v.varyings[i] = varyings[i];
outpt.v.varyings[i] = varyings[i];
#endif
}
@ -104,11 +101,11 @@ layout(vertices = 16) out;
in block {
ControlVertex v;
} input[];
} inpt[];
out block {
ControlVertex v;
} output[];
} outpt[];
#define ID gl_InvocationID
@ -128,7 +125,7 @@ void main()
H[l] = vec3(0,0,0);
for (int k=0; k<4; k++) {
float c = Q[i][k];
H[l] += c*input[l*4 + k].v.position.xyz;
H[l] += c*inpt[l*4 + k].v.position.xyz;
}
}
@ -146,7 +143,7 @@ void main()
H[l] = vec3(0,0,0);
for (int k=0; k<3; k++) {
float c = B[i][2-k];
H[l] += c*input[l*3 + k].v.position.xyz;
H[l] += c*inpt[l*3 + k].v.position.xyz;
}
}
@ -164,7 +161,7 @@ void main()
H[l] = vec3(0,0,0);
for (int k=0; k<4; k++) {
float c = Q[i][k];
H[l] += c*input[l*4 + k].v.position.xyz;
H[l] += c*inpt[l*4 + k].v.position.xyz;
}
}
@ -175,21 +172,20 @@ void main()
#endif
output[ID].v.position = vec4(pos, 1.0);
outpt[ID].v.position = vec4(pos, 1.0);
int patchLevel = GetPatchLevel();
output[ID].v.patchCoord = vec4(0, 0,
patchLevel+0.5,
gl_PrimitiveID+LevelBase+0.5);
outpt[ID].v.patchCoord = vec4(0, 0,
patchLevel+0.5,
gl_PrimitiveID+LevelBase+0.5);
OSD_COMPUTE_PTEX_COORD_TESSCONTROL_SHADER;
if (ID == 0) {
OSD_PATCH_CULL(16);
#if OSD_ENABLE_SCREENSPACE_TESSELLATION
#line 1000
// These tables map the 9, 12, or 16 input control points onto the
#ifdef OSD_ENABLE_SCREENSPACE_TESSELLATION
// These tables map the 9, 12, or 16 inpt control points onto the
// canonical 16 control points for a regular patch.
#if defined BOUNDARY
const int p[16] = int[]( 0, 1, 2, 3, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 );
@ -209,27 +205,26 @@ void main()
const int r[16] = int[]( 3, 7, 11, 15, 2, 6, 10, 14, 1, 5, 9, 13, 0, 4, 8, 12 );
#endif
#line 2000
// Expand and rotate control points using remapping tables above
vec3 pv0 = input[p[r[0]]].v.position.xyz;
vec3 pv1 = input[p[r[1]]].v.position.xyz;
vec3 pv2 = input[p[r[2]]].v.position.xyz;
vec3 pv3 = input[p[r[3]]].v.position.xyz;
vec3 pv0 = inpt[p[r[0]]].v.position.xyz;
vec3 pv1 = inpt[p[r[1]]].v.position.xyz;
vec3 pv2 = inpt[p[r[2]]].v.position.xyz;
vec3 pv3 = inpt[p[r[3]]].v.position.xyz;
vec3 pv4 = input[p[r[4]]].v.position.xyz;
vec3 pv5 = input[p[r[5]]].v.position.xyz;
vec3 pv6 = input[p[r[6]]].v.position.xyz;
vec3 pv7 = input[p[r[7]]].v.position.xyz;
vec3 pv4 = inpt[p[r[4]]].v.position.xyz;
vec3 pv5 = inpt[p[r[5]]].v.position.xyz;
vec3 pv6 = inpt[p[r[6]]].v.position.xyz;
vec3 pv7 = inpt[p[r[7]]].v.position.xyz;
vec3 pv8 = input[p[r[8]]].v.position.xyz;
vec3 pv9 = input[p[r[9]]].v.position.xyz;
vec3 pv10 = input[p[r[10]]].v.position.xyz;
vec3 pv11 = input[p[r[11]]].v.position.xyz;
vec3 pv8 = inpt[p[r[8]]].v.position.xyz;
vec3 pv9 = inpt[p[r[9]]].v.position.xyz;
vec3 pv10 = inpt[p[r[10]]].v.position.xyz;
vec3 pv11 = inpt[p[r[11]]].v.position.xyz;
vec3 pv12 = input[p[r[12]]].v.position.xyz;
vec3 pv13 = input[p[r[13]]].v.position.xyz;
vec3 pv14 = input[p[r[14]]].v.position.xyz;
vec3 pv15 = input[p[r[15]]].v.position.xyz;
vec3 pv12 = inpt[p[r[12]]].v.position.xyz;
vec3 pv13 = inpt[p[r[13]]].v.position.xyz;
vec3 pv14 = inpt[p[r[14]]].v.position.xyz;
vec3 pv15 = inpt[p[r[15]]].v.position.xyz;
// Each edge of a transition patch is adjacent to one or two
// patches at the next refined level of subdivision.
@ -605,11 +600,11 @@ void main()
in block {
ControlVertex v;
} input[];
} inpt[];
out block {
OutputVertex v;
} output;
} outpt;
void main()
{
@ -739,25 +734,25 @@ void main()
vec3 WorldPos, Tangent, BiTangent;
vec3 cp[16];
for(int i = 0; i < 16; ++i) cp[i] = input[i].v.position.xyz;
for(int i = 0; i < 16; ++i) cp[i] = inpt[i].v.position.xyz;
EvalBSpline(UV, cp, WorldPos, Tangent, BiTangent);
vec3 normal = normalize(cross(BiTangent, Tangent));
output.v.position = vec4(WorldPos, 1.0f);
output.v.normal = normal;
output.v.tangent = BiTangent;
outpt.v.position = vec4(WorldPos, 1.0f);
outpt.v.normal = normal;
outpt.v.tangent = BiTangent;
output.v.patchCoord = input[0].v.patchCoord;
outpt.v.patchCoord = inpt[0].v.patchCoord;
#if ROTATE == 1
output.v.patchCoord.xy = vec2(UV.x, 1.0-UV.y);
outpt.v.patchCoord.xy = vec2(UV.x, 1.0-UV.y);
#elif ROTATE == 2
output.v.patchCoord.xy = vec2(1.0-UV.y, 1.0-UV.x);
outpt.v.patchCoord.xy = vec2(1.0-UV.y, 1.0-UV.x);
#elif ROTATE == 3
output.v.patchCoord.xy = vec2(1.0-UV.x, UV.y);
outpt.v.patchCoord.xy = vec2(1.0-UV.x, UV.y);
#else
output.v.patchCoord.xy = vec2(UV.y, UV.x);
outpt.v.patchCoord.xy = vec2(UV.y, UV.x);
#endif
OSD_COMPUTE_PTEX_COORD_TESSEVAL_SHADER;
@ -782,11 +777,11 @@ layout (location=2) in vec4 color;
out block {
OutputVertex v;
} output;
} outpt;
void main() {
gl_Position = ModelViewProjectionMatrix * position;
output.v.color = color;
outpt.v.color = color;
}
#endif
@ -798,9 +793,9 @@ void main() {
in block {
OutputVertex v;
} input;
} inpt;
void main() {
gl_FragColor = input.v.color;
gl_FragColor = inpt.v.color;
}
#endif

View File

@ -55,27 +55,15 @@
// a particular purpose and non-infringement.
//
#if defined(__APPLE__)
#include "TargetConditionals.h"
#if TARGET_OS_IPHONE or TARGET_IPHONE_SIMULATOR
#include <OpenGLES/ES2/gl.h>
#else
#include <OpenGL/gl3.h>
#endif
#elif defined(ANDROID)
#include <GLES2/gl2.h>
#else
#if defined(_WIN32)
#include <windows.h>
#endif
#include <GL/glew.h>
#endif
#include "../version.h"
#include "../far/mesh.h"
#include "../far/subdivisionTables.h"
#include "../osd/glslTransformFeedbackComputeContext.h"
#include "../osd/glslTransformFeedbackKernelBundle.h"
#include "../osd/opengl.h"
namespace OpenSubdiv {
namespace OPENSUBDIV_VERSION {

View File

@ -57,22 +57,6 @@
#ifndef OSD_GLSL_TRANSFORM_FEEDBACK_COMPUTE_CONTEXT_H
#define OSD_GLSL_TRANSFORM_FEEDBACK_COMPUTE_CONTEXT_H
#if defined(__APPLE__)
#include "TargetConditionals.h"
#if TARGET_OS_IPHONE or TARGET_IPHONE_SIMULATOR
#include <OpenGLES/ES2/gl.h>
#else
#include <OpenGL/gl3.h>
#endif
#elif defined(ANDROID)
#include <GLES2/gl2.h>
#else
#if defined(_WIN32)
#include <windows.h>
#endif
#include <GL/gl.h>
#endif
#include "../version.h"
#include "../far/vertexEditTables.h"
@ -80,6 +64,8 @@
#include "../osd/vertexDescriptor.h"
#include "../osd/nonCopyable.h"
#include "../osd/opengl.h"
#include <vector>
namespace OpenSubdiv {

View File

@ -55,16 +55,12 @@
// a particular purpose and non-infringement.
//
#if defined(__APPLE__)
#include <OpenGL/gl3.h>
#else
#include <GL/glew.h>
#endif
#include "../osd/glslTransformFeedbackComputeController.h"
#include "../osd/glslTransformFeedbackComputeContext.h"
#include "../osd/glslTransformFeedbackKernelBundle.h"
#include "../osd/opengl.h"
#include <algorithm>
#include <cassert>

View File

@ -55,11 +55,7 @@
// a particular purpose and non-infringement.
//
#if defined(__APPLE__)
#include <OpenGL/gl3.h>
#else
#include <GL/glew.h>
#endif
#include "../version.h"
#include <stdio.h>
#ifdef _MSC_VER
@ -73,6 +69,8 @@
#include "../far/subdivisionTables.h"
#include "../osd/opengl.h"
#include <cassert>
namespace OpenSubdiv {

View File

@ -57,28 +57,15 @@
#ifndef OSD_GLSL_TRANSFORM_FEEDBACK_KERNEL_BUNDLE_H
#define OSD_GLSL_TRANSFORM_FEEDBACK_KERNEL_BUNDLE_H
#if defined(__APPLE__)
#include "TargetConditionals.h"
#if TARGET_OS_IPHONE or TARGET_IPHONE_SIMULATOR
#include <OpenGLES/ES2/gl.h>
#else
#include <OpenGL/gl3.h>
#endif
#elif defined(ANDROID)
#include <GLES2/gl2.h>
#else
#if defined(_WIN32)
#include <windows.h>
#endif
#include <GL/gl.h>
#endif
#include "../version.h"
#include "../osd/nonCopyable.h"
#include "../osd/vertex.h"
#include "../osd/vertexDescriptor.h"
#include "../far/subdivisionTables.h"
#include "../osd/opengl.h"
namespace OpenSubdiv {
namespace OPENSUBDIV_VERSION {

View File

@ -54,89 +54,24 @@
// exclude the implied warranties of merchantability, fitness for
// a particular purpose and non-infringement.
//
#ifndef OSD_OPENGL_H
#define OSD_OPENGL_H
//--------------------------------------------------------------
// Vertex Shader
//--------------------------------------------------------------
#ifdef VERTEX_SHADER
layout (location=0) in vec3 position;
layout (location=1) in vec3 normal;
uniform mat4 objectToClipMatrix;
uniform mat4 objectToEyeMatrix;
out vec3 vPosition;
out vec3 vNormalEye;
void main()
{
// vertex position in object space
vPosition = position;
// vertex position in clip space
gl_Position = objectToClipMatrix * vec4(position, 1);
// surface normal in eye space
vNormalEye = (objectToEyeMatrix * vec4(normal, 0)).xyz;
}
#if defined(__APPLE__)
#include "TargetConditionals.h"
#if TARGET_OS_IPHONE or TARGET_IPHONE_SIMULATOR
#include <OpenGLES/ES2/gl.h>
#else
#include <OpenGL/gl3.h>
#endif
#elif defined(ANDROID)
#include <GLES2/gl2.h>
#else
#if defined(_WIN32)
#define W32_LEAN_AND_MEAN
#include <windows.h>
#endif
#include <GL/glew.h>
#endif
//--------------------------------------------------------------
// Fragment Shader
//--------------------------------------------------------------
#ifdef FRAGMENT_SHADER
layout (location=0) out vec4 FragColor;
in vec3 vNormalEye;
in vec3 vPosition;
#define NUM_LIGHTS 2
struct LightSource {
vec4 position;
vec4 ambient;
vec4 diffuse;
vec4 specular;
};
uniform LightSource lightSource[NUM_LIGHTS];
vec4
lighting(vec3 Peye, vec3 Neye)
{
vec4 color = vec4(0);
vec4 material = vec4(0.4, 0.4, 0.8, 1);
for (int i = 0; i < NUM_LIGHTS; ++i) {
vec4 Plight = lightSource[i].position;
vec3 l = (Plight.w == 0.0)
? normalize(Plight.xyz) : normalize(Plight.xyz - Peye);
vec3 n = normalize(Neye);
vec3 h = normalize(l + vec3(0,0,1)); // directional viewer
float d = max(0.0, dot(n, l));
float s = pow(max(0.0, dot(n, h)), 500.0f);
color += lightSource[i].ambient * material
+ d * lightSource[i].diffuse * material
+ s * lightSource[i].specular;
}
color.a = 1;
return color;
}
void
main()
{
vec3 N = (gl_FrontFacing ? vNormalEye : -vNormalEye);
FragColor = lighting(vPosition, N);
FragColor = vec4(1,0,0,1);
}
#endif
#endif // OSD_OPENGL_H

View File

@ -213,7 +213,7 @@ struct OsdVertexBufferDescriptor {
/// True if the descriptor values are internally consistent
bool IsValid() const {
return (offset<length) and (stride>=length);
return (length>0) and (offset<length) and (stride>=length);
}
/// True if the 'other' descriptor can be used as a destination for
@ -225,6 +225,11 @@ struct OsdVertexBufferDescriptor {
(other.length <= (stride-offset));
}
/// Resets the descriptor to default
void Reset() {
offset = length = stride = 0;
}
int offset; // offset to desired element data
int length; // number or length of the data
int stride; // stride to the next element

View File

@ -66,11 +66,18 @@ include_directories(
set(PUBLIC_HEADER_FILES
batch.h
batchCL.h
drawItem.h
drawController.h
)
#-------------------------------------------------------------------------------
# OpenCL code & dependencies
if ( OPENCL_FOUND )
list(APPEND PUBLIC_HEADER_FILES
batchCL.h
)
endif()
#-------------------------------------------------------------------------------
# platform dependent tweaks

View File

@ -66,8 +66,6 @@
namespace OpenSubdiv {
namespace OPENSUBDIV_VERSION {
#ifdef OPENSUBDIV_HAS_OPENCL
// ----------------------------------------------------------------------------
// OsdUtilMeshBatch OpenCL specialized class
//
@ -237,8 +235,6 @@ OsdUtilMeshBatch<VERTEX_BUFFER, DRAW_CONTEXT, OsdCLComputeController>::Create(Co
return batch;
}
#endif /* OPENSUBDIV_HAS_OPENCL */
} // end namespace OPENSUBDIV_VERSION
using namespace OPENSUBDIV_VERSION;

View File

@ -58,6 +58,6 @@
#ifndef OPENSUBDIV_VERSION_H
#define OPENSUBDIV_VERSION_H
#define OPENSUBDIV_VERSION v1_2_2
#define OPENSUBDIV_VERSION v1_2_3
#endif /* OPENSUBDIV_VERSION_H */

View File

@ -129,6 +129,8 @@ struct shape {
int getNverts() const { return (int)verts.size()/3; }
int getNfaces() const { return (int)nvertsPerFace.size(); }
bool hasUV() const { return not (uvs.empty() or faceuvs.empty()); }
std::vector<float> verts;
std::vector<float> uvs;
@ -703,7 +705,7 @@ hbrToObj( OpenSubdiv::HbrMesh<T> * mesh ) {
//------------------------------------------------------------------------------
template <class T> OpenSubdiv::HbrMesh<T> *
createMesh( Scheme scheme=kCatmark) {
createMesh( Scheme scheme=kCatmark, int fvarwidth=0) {
OpenSubdiv::HbrMesh<T> * mesh = 0;
@ -711,10 +713,32 @@ createMesh( Scheme scheme=kCatmark) {
static OpenSubdiv::HbrLoopSubdivision<T> _loop;
static OpenSubdiv::HbrCatmarkSubdivision<T> _catmark;
static int indices[1] = { 0 },
widths[1] = { 2 };
int const fvarcount = fvarwidth > 0 ? 1 : 0,
* fvarindices = fvarwidth > 0 ? indices : NULL,
* fvarwidths = fvarwidth > 0 ? widths : NULL;
switch (scheme) {
case kBilinear : mesh = new OpenSubdiv::HbrMesh<T>( &_bilinear ); break;
case kLoop : mesh = new OpenSubdiv::HbrMesh<T>( &_loop ); break;
case kCatmark : mesh = new OpenSubdiv::HbrMesh<T>( &_catmark ); break;
case kBilinear : mesh = new OpenSubdiv::HbrMesh<T>( &_bilinear,
fvarcount,
fvarindices,
fvarwidths,
fvarwidth ); break;
case kLoop : mesh = new OpenSubdiv::HbrMesh<T>( &_loop,
fvarcount,
fvarindices,
fvarwidths,
fvarwidth ); break;
case kCatmark : mesh = new OpenSubdiv::HbrMesh<T>( &_catmark,
fvarcount,
fvarindices,
fvarwidths,
fvarwidth ); break;
}
return mesh;
@ -838,21 +862,63 @@ createTopology( shape const * sh, OpenSubdiv::HbrMesh<T> * mesh, Scheme scheme)
applyTags<T>( mesh, sh );
mesh->Finish();
// check for disconnected vertices
if (mesh->GetNumDisconnectedVertices()) {
printf("The specified subdivmesh contains disconnected surface components.\n");
exit(1);
}
}
//------------------------------------------------------------------------------
template <class T> void
createFaceVaryingUV( shape const * sh, OpenSubdiv::HbrMesh<T> * mesh) {
if (not sh->hasUV())
return;
for (int i=0, idx=0; i<sh->getNfaces(); ++i ) {
OpenSubdiv::HbrFace<T> * f = mesh->GetFace(i);
int nv = sh->nvertsPerFace[i];
OpenSubdiv::HbrHalfedge<T> * e = f->GetFirstEdge();
for (int j=0; j<nv; ++j, e=e->GetNext()) {
OpenSubdiv::HbrFVarData<T> & fvt = e->GetOrgVertex()->GetFVarData(f);
float const * fvdata = &sh->uvs[ sh->faceuvs[idx++]*2 ];
if (not fvt.IsInitialized()) {
fvt.SetAllData(2, fvdata);
} else if (not fvt.CompareAll(2, fvdata)) {
OpenSubdiv::HbrFVarData<T> & nfvt = e->GetOrgVertex()->NewFVarData(f);
nfvt.SetAllData(2, fvdata);
}
}
}
}
//------------------------------------------------------------------------------
template <class T> OpenSubdiv::HbrMesh<T> *
simpleHbr(char const * shapestr, Scheme scheme, std::vector<float> * verts=0) {
simpleHbr(char const * shapestr, Scheme scheme, std::vector<float> * verts=0, bool fvar=false) {
shape * sh = shape::parseShape( shapestr );
OpenSubdiv::HbrMesh<T> * mesh = createMesh<T>(scheme);
int fvarwidth = fvar and sh->hasUV() ? 2 : 0;
OpenSubdiv::HbrMesh<T> * mesh = createMesh<T>(scheme, fvarwidth);
createVertices<T>(sh, mesh, verts);
createTopology<T>(sh, mesh, scheme);
if (fvar)
createFaceVaryingUV<T>(sh, mesh);
if(verts)
if (verts)
copyVertexPositions<T>(sh,mesh,*verts);
delete sh;
@ -862,16 +928,21 @@ simpleHbr(char const * shapestr, Scheme scheme, std::vector<float> * verts=0) {
//------------------------------------------------------------------------------
template <class T> OpenSubdiv::HbrMesh<T> *
simpleHbr(char const * shapestr, Scheme scheme, std::vector<float> & verts) {
simpleHbr(char const * shapestr, Scheme scheme, std::vector<float> & verts, bool fvar=false) {
shape * sh = shape::parseShape( shapestr );
OpenSubdiv::HbrMesh<T> * mesh = createMesh<T>(scheme);
int fvarwidth = fvar and sh->hasUV() ? 2 : 0;
OpenSubdiv::HbrMesh<T> * mesh = createMesh<T>(scheme, fvarwidth);
createVertices<T>(sh, mesh, verts);
createTopology<T>(sh, mesh, scheme);
if (fvar)
createFaceVaryingUV<T>(sh, mesh);
copyVertexPositions<T>(sh,mesh,verts);
delete sh;

View File

@ -82,31 +82,31 @@ static const std::string catmark_dart_edgecorner =
"v -1.000000 0.000000 0.000000\n"
"v -0.500000 0.500000 0.000000\n"
"v 0.000000 1.000000 0.000000\n"
"vt 0.000000 0.000000\n"
"vt 0.000000 0.000000\n"
"vt 0.000000 0.000000\n"
"vt 0.000000 0.000000\n"
"vt 0.000000 0.000000\n"
"vt 0.000000 0.000000\n"
"vt 0.000000 0.000000\n"
"vt 0.000000 0.000000\n"
"vt 0.000000 0.000000\n"
"vt 0.000000 0.000000\n"
"vt 0.000000 0.000000\n"
"vt 0.000000 0.000000\n"
"vt 0.000000 0.000000\n"
"vt 0.000000 0.000000\n"
"vt 0.000000 0.000000\n"
"vt 0.000000 0.000000\n"
"vt 0.000000 0.000000\n"
"vt 0.000000 0.000000\n"
"vt 0.000000 0.000000\n"
"vt 0.000000 0.000000\n"
"vt 0.000000 0.000000\n"
"vt 0.000000 0.000000\n"
"vt 0.000000 0.000000\n"
"vt 0.000000 0.000000\n"
"vt 0.000000 0.000000\n"
"vt 0.000000 0.500000\n"
"vt 0.125000 0.375000\n"
"vt 0.250000 0.500000\n"
"vt 0.125000 0.625000\n"
"vt 0.875000 0.625000\n"
"vt 0.750000 0.500000\n"
"vt 0.875000 0.375000\n"
"vt 1.000000 0.500000\n"
"vt 0.625000 0.125000\n"
"vt 0.500000 0.250000\n"
"vt 0.375000 0.125000\n"
"vt 0.500000 0.000000\n"
"vt 0.750000 0.250000\n"
"vt 0.625000 0.375000\n"
"vt 0.750000 0.750000\n"
"vt 0.625000 0.625000\n"
"vt 0.375000 0.375000\n"
"vt 0.250000 0.250000\n"
"vt 0.500000 0.500000\n"
"vt 0.625000 0.875000\n"
"vt 0.500000 0.750000\n"
"vt 0.375000 0.625000\n"
"vt 0.375000 0.875000\n"
"vt 0.500000 1.000000\n"
"vt 0.250000 0.750000\n"
"vn 1.000000 0.000000 0.000000\n"
"vn 0.000000 0.000000 1.000000\n"
"vn -0.187366 0.000000 0.982290\n"
@ -133,22 +133,22 @@ static const std::string catmark_dart_edgecorner =
"vn 1.000000 0.000000 0.000000\n"
"vn 0.000000 0.000000 1.000000\n"
"s 1\n"
"f 4/1/1 7/7/2 23/23/3 14/14/4\n"
"f 13/13/5 19/19/6 8/8/7 2/3/8\n"
"f 10/10/9 17/17/10 5/5/11 1/4/12\n"
"f 9/9/13 18/18/14 17/17/10 10/10/9\n"
"f 8/8/7 19/19/6 18/18/14 9/9/13\n"
"f 12/12/15 22/22/16 19/19/6 13/13/5\n"
"f 17/17/10 20/20/17 6/6/18 5/5/11\n"
"f 18/18/14 21/21/19 20/20/17 17/17/10\n"
"f 19/19/6 22/22/16 21/21/19 18/18/14\n"
"f 11/11/20 25/25/21 22/22/16 12/12/15\n"
"f 20/20/17 23/23/3 7/7/2 6/6/18\n"
"f 21/21/19 24/24/22 23/23/3 20/20/17\n"
"f 22/22/16 25/25/21 24/24/22 21/21/19\n"
"f 16/16/23 25/25/21 11/11/20 3/2/24\n"
"f 15/15/25 24/24/22 25/25/21 16/16/23\n"
"f 14/14/4 23/23/3 24/24/22 15/15/25\n"
"f 4/1/1 7/2/2 23/3/3 14/4/4\n"
"f 13/5/5 19/6/6 8/7/7 2/8/8\n"
"f 10/9/9 17/10/10 5/11/11 1/12/12\n"
"f 9/13/13 18/14/14 17/10/15 10/9/16\n"
"f 8/7/17 19/6/18 18/14/19 9/13/20\n"
"f 12/15/21 22/16/22 19/6/23 13/5/24\n"
"f 17/10/25 20/17/26 6/18/27 5/11/28\n"
"f 18/14/29 21/19/30 20/17/31 17/10/32\n"
"f 19/6/33 22/16/34 21/19/35 18/14/36\n"
"f 11/20/37 25/21/38 22/16/39 12/15/40\n"
"f 20/17/41 23/3/42 7/2/43 6/18/44\n"
"f 21/19/45 24/22/46 23/3/47 20/17/48\n"
"f 22/16/49 25/21/50 24/22/51 21/19/52\n"
"f 16/23/53 25/21/54 11/20/55 3/24/56\n"
"f 15/25/57 24/22/58 25/21/59 16/23/60\n"
"f 14/4/61 23/3/62 24/22/63 15/25/64\n"
"t crease 2/1/0 8 17 2.0\n"
"t crease 2/1/0 17 20 2.0\n"
"t interpolateboundary 1/0/0 1\n"

View File

@ -82,31 +82,31 @@ static const std::string catmark_dart_edgeonly =
"v -1.000000 0.000000 0.000000\n"
"v -0.500000 0.500000 0.000000\n"
"v 0.000000 1.000000 0.000000\n"
"vt 0.000000 0.000000\n"
"vt 0.000000 0.000000\n"
"vt 0.000000 0.000000\n"
"vt 0.000000 0.000000\n"
"vt 0.000000 0.000000\n"
"vt 0.000000 0.000000\n"
"vt 0.000000 0.000000\n"
"vt 0.000000 0.000000\n"
"vt 0.000000 0.000000\n"
"vt 0.000000 0.000000\n"
"vt 0.000000 0.000000\n"
"vt 0.000000 0.000000\n"
"vt 0.000000 0.000000\n"
"vt 0.000000 0.000000\n"
"vt 0.000000 0.000000\n"
"vt 0.000000 0.000000\n"
"vt 0.000000 0.000000\n"
"vt 0.000000 0.000000\n"
"vt 0.000000 0.000000\n"
"vt 0.000000 0.000000\n"
"vt 0.000000 0.000000\n"
"vt 0.000000 0.000000\n"
"vt 0.000000 0.000000\n"
"vt 0.000000 0.000000\n"
"vt 0.000000 0.000000\n"
"vt 0.000000 0.500000\n"
"vt 0.125000 0.375000\n"
"vt 0.250000 0.500000\n"
"vt 0.125000 0.625000\n"
"vt 0.875000 0.625000\n"
"vt 0.750000 0.500000\n"
"vt 0.875000 0.375000\n"
"vt 1.000000 0.500000\n"
"vt 0.625000 0.125000\n"
"vt 0.500000 0.250000\n"
"vt 0.375000 0.125000\n"
"vt 0.500000 0.000000\n"
"vt 0.750000 0.250000\n"
"vt 0.625000 0.375000\n"
"vt 0.750000 0.750000\n"
"vt 0.625000 0.625000\n"
"vt 0.375000 0.375000\n"
"vt 0.250000 0.250000\n"
"vt 0.500000 0.500000\n"
"vt 0.625000 0.875000\n"
"vt 0.500000 0.750000\n"
"vt 0.375000 0.625000\n"
"vt 0.375000 0.875000\n"
"vt 0.500000 1.000000\n"
"vt 0.250000 0.750000\n"
"vn 1.000000 0.000000 0.000000\n"
"vn 0.000000 0.000000 1.000000\n"
"vn -0.187366 0.000000 0.982290\n"
@ -133,22 +133,22 @@ static const std::string catmark_dart_edgeonly =
"vn 1.000000 0.000000 0.000000\n"
"vn 0.000000 0.000000 1.000000\n"
"s 1\n"
"f 4/1/1 7/7/2 23/23/3 14/14/4\n"
"f 13/13/5 19/19/6 8/8/7 2/3/8\n"
"f 10/10/9 17/17/10 5/5/11 1/4/12\n"
"f 9/9/13 18/18/14 17/17/10 10/10/9\n"
"f 8/8/7 19/19/6 18/18/14 9/9/13\n"
"f 12/12/15 22/22/16 19/19/6 13/13/5\n"
"f 17/17/10 20/20/17 6/6/18 5/5/11\n"
"f 18/18/14 21/21/19 20/20/17 17/17/10\n"
"f 19/19/6 22/22/16 21/21/19 18/18/14\n"
"f 11/11/20 25/25/21 22/22/16 12/12/15\n"
"f 20/20/17 23/23/3 7/7/2 6/6/18\n"
"f 21/21/19 24/24/22 23/23/3 20/20/17\n"
"f 22/22/16 25/25/21 24/24/22 21/21/19\n"
"f 16/16/23 25/25/21 11/11/20 3/2/24\n"
"f 15/15/25 24/24/22 25/25/21 16/16/23\n"
"f 14/14/4 23/23/3 24/24/22 15/15/25\n"
"f 4/1/1 7/2/2 23/3/3 14/4/4\n"
"f 13/5/5 19/6/6 8/7/7 2/8/8\n"
"f 10/9/9 17/10/10 5/11/11 1/12/12\n"
"f 9/13/13 18/14/14 17/10/15 10/9/16\n"
"f 8/7/17 19/6/18 18/14/19 9/13/20\n"
"f 12/15/21 22/16/22 19/6/23 13/5/24\n"
"f 17/10/25 20/17/26 6/18/27 5/11/28\n"
"f 18/14/29 21/19/30 20/17/31 17/10/32\n"
"f 19/6/33 22/16/34 21/19/35 18/14/36\n"
"f 11/20/37 25/21/38 22/16/39 12/15/40\n"
"f 20/17/41 23/3/42 7/2/43 6/18/44\n"
"f 21/19/45 24/22/46 23/3/47 20/17/48\n"
"f 22/16/49 25/21/50 24/22/51 21/19/52\n"
"f 16/23/53 25/21/54 11/20/55 3/24/56\n"
"f 15/25/57 24/22/58 25/21/59 16/23/60\n"
"f 14/4/61 23/3/62 24/22/63 15/25/64\n"
"t crease 2/1/0 8 17 2.0\n"
"t crease 2/1/0 17 20 2.0\n"
"t interpolateboundary 1/0/0 2\n"

View File

@ -62,9 +62,9 @@ static const std::string catmark_edgecorner =
"v 0.0 2.0 0.0\n"
"v -2.0 0.0 0.0\n"
"vt 0.0 0.0\n"
"vt 0.0 0.0\n"
"vt 0.0 0.0\n"
"vt 0.0 0.0\n"
"vt 1.0 0.0\n"
"vt 0.0 1.0\n"
"vt 1.0 1.0\n"
"vn 0.0 0.0 0.0\n"
"vn 0.0 0.0 0.0\n"
"vn 0.0 0.0 0.0\n"

View File

@ -62,9 +62,9 @@ static const std::string catmark_edgeonly =
"v 0.0 2.0 0.0\n"
"v -2.0 0.0 0.0\n"
"vt 0.0 0.0\n"
"vt 0.0 0.0\n"
"vt 0.0 0.0\n"
"vt 0.0 0.0\n"
"vt 1.0 0.0\n"
"vt 0.0 1.0\n"
"vt 1.0 1.0\n"
"vn 0.0 0.0 0.0\n"
"vn 0.0 0.0 0.0\n"
"vn 0.0 0.0 0.0\n"

View File

@ -69,20 +69,6 @@ static const std::string catmark_gregory_test3 =
"v -2.000000 1.000000 -0.000000\n"
"v -2.000000 0.000000 0.000000\n"
"v -2.000000 -1.000000 0.000000\n"
"vt 0 0 \n"
"vt 0 0 \n"
"vt 0 0 \n"
"vt 0 0 \n"
"vt 0 0 \n"
"vt 0 0 \n"
"vt 0 0 \n"
"vt 0 0 \n"
"vt 0 0 \n"
"vt 0 0 \n"
"vt 0 0 \n"
"vt 0 0 \n"
"vt 0 0 \n"
"vt 0 0 \n"
"vn 0.518841 0.518841 0.679418\n"
"vn 0.606923 0.000000 0.794761\n"
"vn 0.518841 -0.518841 0.679418\n"

View File

@ -62,16 +62,14 @@ static const std::string catmark_pyramid =
"v 2.0 0.0 0.0\n"
"v 0.0 2.0 0.0\n"
"v -2.0 0.0 0.0\n"
"vt 0.0 0.0\n"
"vt 0.0 0.0\n"
"vt 0.0 0.0\n"
"vt 0.0 0.0\n"
"vt 0.0 0.0\n"
"vt 0.0 0.0\n"
"vt 0.0 0.0\n"
"vt 0.0 0.0\n"
"vt 0.0 0.0\n"
"vt 0.0 0.0\n"
"vt 0.500000 0.000000\n"
"vt 0.000000 0.500000\n"
"vt 0.500000 1.000000\n"
"vt 1.000000 0.500000\n"
"vt 1.000000 1.000000\n"
"vt 0.000000 1.000000\n"
"vt 0.000000 0.000000\n"
"vt 1.000000 0.000000\n"
"vn 0.0 0.0 0.0\n"
"vn 0.0 0.0 0.0\n"
"vn 0.0 0.0 0.0\n"
@ -89,10 +87,10 @@ static const std::string catmark_pyramid =
"vn 0.0 0.0 0.0\n"
"vn 0.0 0.0 0.0\n"
"s off\n"
"f 1/1/1 2/2/2 3/3/3\n"
"f 1/1/1 3/3/3 4/4/4\n"
"f 1/1/1 4/4/4 5/5/5\n"
"f 1/1/1 5/5/5 2/2/2\n"
"f 5/5/5 4/4/4 3/3/3 2/2/2\n"
"f 1/5/1 2/4/2 3/3/3\n"
"f 1/6/1 3/3/3 4/2/4\n"
"f 1/7/1 4/2/4 5/1/5\n"
"f 1/8/1 5/1/5 2/4/2\n"
"f 5/1/5 4/2/4 3/3/3 2/4/2\n"
"\n"
;

View File

@ -62,32 +62,6 @@ static const std::string catmark_pyramid_creases0 =
"v 2.0 0.0 0.0\n"
"v 0.0 2.0 0.0\n"
"v -2.0 0.0 0.0\n"
"vt 0.0 0.0\n"
"vt 0.0 0.0\n"
"vt 0.0 0.0\n"
"vt 0.0 0.0\n"
"vt 0.0 0.0\n"
"vt 0.0 0.0\n"
"vt 0.0 0.0\n"
"vt 0.0 0.0\n"
"vt 0.0 0.0\n"
"vt 0.0 0.0\n"
"vn 0.0 0.0 0.0\n"
"vn 0.0 0.0 0.0\n"
"vn 0.0 0.0 0.0\n"
"vn 0.0 0.0 0.0\n"
"vn 0.0 0.0 0.0\n"
"vn 0.0 0.0 0.0\n"
"vn 0.0 0.0 0.0\n"
"vn 0.0 0.0 0.0\n"
"vn 0.0 0.0 0.0\n"
"vn 0.0 0.0 0.0\n"
"vn 0.0 0.0 0.0\n"
"vn 0.0 0.0 0.0\n"
"vn 0.0 0.0 0.0\n"
"vn 0.0 0.0 0.0\n"
"vn 0.0 0.0 0.0\n"
"vn 0.0 0.0 0.0\n"
"s off\n"
"f 1/1/1 2/2/2 3/3/3\n"
"f 1/1/1 3/3/3 4/4/4\n"

View File

@ -62,32 +62,6 @@ static const std::string catmark_pyramid_creases1 =
"v 2.0 0.0 0.0\n"
"v 0.0 2.0 0.0\n"
"v -2.0 0.0 0.0\n"
"vt 0.0 0.0\n"
"vt 0.0 0.0\n"
"vt 0.0 0.0\n"
"vt 0.0 0.0\n"
"vt 0.0 0.0\n"
"vt 0.0 0.0\n"
"vt 0.0 0.0\n"
"vt 0.0 0.0\n"
"vt 0.0 0.0\n"
"vt 0.0 0.0\n"
"vn 0.0 0.0 0.0\n"
"vn 0.0 0.0 0.0\n"
"vn 0.0 0.0 0.0\n"
"vn 0.0 0.0 0.0\n"
"vn 0.0 0.0 0.0\n"
"vn 0.0 0.0 0.0\n"
"vn 0.0 0.0 0.0\n"
"vn 0.0 0.0 0.0\n"
"vn 0.0 0.0 0.0\n"
"vn 0.0 0.0 0.0\n"
"vn 0.0 0.0 0.0\n"
"vn 0.0 0.0 0.0\n"
"vn 0.0 0.0 0.0\n"
"vn 0.0 0.0 0.0\n"
"vn 0.0 0.0 0.0\n"
"vn 0.0 0.0 0.0\n"
"s off\n"
"f 1/1/1 2/2/2 3/3/3\n"
"f 1/1/1 3/3/3 4/4/4\n"

View File

@ -73,8 +73,6 @@ static const std::string catmark_square_hedit0 =
"v -0.333333 1 0\n"
"v 0.333333 1 0\n"
"v 1 1 0\n"
"vt 0.0 0.0\n"
"vn 0.0 0.0 0.0\n"
"s off\n"
"f 1/1/1 2/1/1 6/1/1 5/1/1\n"
"f 2/1/1 3/1/1 7/1/1 6/1/1\n"

View File

@ -73,8 +73,6 @@ static const std::string catmark_square_hedit1 =
"v -0.333333 1 0\n"
"v 0.333333 1 0\n"
"v 1 1 0\n"
"vt 0.0 0.0\n"
"vn 0.0 0.0 0.0\n"
"s off\n"
"f 1/1/1 2/1/1 6/1/1 5/1/1\n"
"f 2/1/1 3/1/1 7/1/1 6/1/1\n"

View File

@ -73,8 +73,6 @@ static const std::string catmark_square_hedit2 =
"v -0.333333 1 0\n"
"v 0.333333 1 0\n"
"v 1 1 0\n"
"vt 0.0 0.0\n"
"vn 0.0 0.0 0.0\n"
"s off\n"
"f 1/1/1 2/1/1 6/1/1 5/1/1\n"
"f 2/1/1 3/1/1 7/1/1 6/1/1\n"

View File

@ -73,8 +73,6 @@ static const std::string catmark_square_hedit3 =
"v -0.333333 1 0\n"
"v 0.333333 1 0\n"
"v 1 1 0\n"
"vt 0.0 0.0\n"
"vn 0.0 0.0 0.0\n"
"s off\n"
"f 1/1/1 2/1/1 6/1/1 5/1/1\n"
"f 2/1/1 3/1/1 7/1/1 6/1/1\n"

View File

@ -73,8 +73,6 @@ static const std::string catmark_square_hedit4 =
"v -0.333333 1 0\n"
"v 0.333333 1 0\n"
"v 1 1 0\n"
"vt 0.0 0.0\n"
"vn 0.0 0.0 0.0\n"
"s off\n"
"f 1/1/1 2/1/1 6/1/1 5/1/1\n"
"f 2/1/1 3/1/1 7/1/1 6/1/1\n"