mirror of
https://github.com/PixarAnimationStudios/OpenSubdiv
synced 2024-12-22 16:00:07 +00:00
Merge branch 'release/v1_2_3'
This commit is contained in:
commit
9f5c2df769
@ -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
|
||||
|
@ -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];
|
||||
|
@ -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}
|
||||
)
|
||||
|
@ -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
@ -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";
|
||||
}
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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"
|
||||
|
@ -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;
|
||||
|
@ -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');
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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];
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -69,6 +69,7 @@ set(PUBLIC_HEADER_FILES
|
||||
mesh.h
|
||||
multiMeshFactory.h
|
||||
patchParam.h
|
||||
patchMap.h
|
||||
patchTables.h
|
||||
patchTablesFactory.h
|
||||
subdivisionTables.h
|
||||
|
@ -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
366
opensubdiv/far/patchMap.h
Normal 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 */
|
@ -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;
|
||||
|
||||
|
@ -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
|
||||
|
@ -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];
|
||||
}
|
||||
|
||||
|
@ -115,6 +115,7 @@ set(PUBLIC_HEADER_FILES
|
||||
evalLimitContext.h
|
||||
mesh.h
|
||||
nonCopyable.h
|
||||
opengl.h
|
||||
drawContext.h
|
||||
drawRegistry.h
|
||||
vertex.h
|
||||
|
@ -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 {
|
||||
|
@ -59,6 +59,8 @@
|
||||
|
||||
#include "../version.h"
|
||||
|
||||
#include "../osd/opengl.h"
|
||||
|
||||
#if defined(__APPLE__)
|
||||
#include <OpenCL/opencl.h>
|
||||
#else
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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
|
||||
|
@ -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 );
|
||||
|
||||
};
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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,
|
||||
|
@ -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 {
|
||||
|
@ -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 {
|
||||
|
@ -58,6 +58,7 @@
|
||||
#define OSD_CPU_KERNEL_H
|
||||
|
||||
#include "../version.h"
|
||||
|
||||
#include "../osd/vertexDescriptor.h"
|
||||
|
||||
namespace OpenSubdiv {
|
||||
|
@ -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 {
|
||||
|
@ -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 {
|
||||
|
||||
|
@ -58,6 +58,7 @@
|
||||
#define OSD_DRAW_CONTEXT_H
|
||||
|
||||
#include "../version.h"
|
||||
|
||||
#include "../far/patchTables.h"
|
||||
|
||||
#include <utility>
|
||||
|
@ -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 {
|
||||
|
||||
|
@ -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 {
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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 {
|
||||
|
@ -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 {
|
||||
|
@ -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 {
|
||||
|
@ -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 {
|
||||
|
@ -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 {
|
||||
|
||||
|
@ -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 {
|
||||
|
||||
|
@ -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 {
|
||||
|
||||
|
@ -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 {
|
||||
|
@ -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>
|
||||
|
||||
|
@ -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 {
|
||||
|
@ -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 {
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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 {
|
||||
|
||||
|
@ -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 {
|
||||
|
@ -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>
|
||||
|
||||
|
@ -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 {
|
||||
|
@ -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 {
|
||||
|
||||
|
@ -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
|
@ -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
|
||||
|
@ -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
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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 */
|
||||
|
@ -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;
|
||||
|
@ -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"
|
||||
|
@ -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"
|
||||
|
@ -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"
|
||||
|
@ -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"
|
||||
|
@ -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"
|
||||
|
@ -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"
|
||||
;
|
||||
|
@ -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"
|
||||
|
@ -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"
|
||||
|
@ -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"
|
||||
|
@ -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"
|
||||
|
@ -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"
|
||||
|
@ -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"
|
||||
|
@ -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"
|
||||
|
Loading…
Reference in New Issue
Block a user