Add Chromium-only Blender WebEngine parity work

This commit is contained in:
mes123456
2026-08-12 04:47:48 -04:00
commit 9fd26010f6
18225 changed files with 11622124 additions and 0 deletions

View File

@@ -0,0 +1,54 @@
#
# Copyright 2013 Pixar
#
# Licensed under the terms set forth in the LICENSE.txt file available at
# https://opensubdiv.org/license.
#
# *** farViewer ***
set(SHADER_FILES
faceShader.glsl
simpleShader.glsl
fontShader.glsl
)
include_directories(
"${OPENSUBDIV_INCLUDE_DIR}"
"${OPENGL_LOADER_INCLUDE_DIRS}"
"${GLFW_INCLUDE_DIR}"
)
list(APPEND PLATFORM_LIBRARIES
"${OSD_LINK_TARGET}"
"${OPENGL_LOADER_LIBRARIES}"
"${GLFW_LIBRARIES}"
)
if (OPENCL_FOUND)
include_directories("${OPENCL_INCLUDE_DIRS}")
list(APPEND PLATFORM_LIBRARIES OpenGL::GL)
endif()
osd_stringify("${SHADER_FILES}" INC_FILES)
include_directories("${CMAKE_CURRENT_BINARY_DIR}")
osd_add_glfw_executable(farViewer "examples"
farViewer.cpp
gl_fontutils.cpp
gl_mesh.cpp
face_texture.cpp
"${SHADER_FILES}"
"${INC_FILES}"
$<TARGET_OBJECTS:sdc_obj>
$<TARGET_OBJECTS:vtr_obj>
$<TARGET_OBJECTS:far_obj>
$<TARGET_OBJECTS:regression_common_obj>
$<TARGET_OBJECTS:examples_common_gl_obj>
)
target_link_libraries(farViewer
${PLATFORM_LIBRARIES}
)
install(TARGETS farViewer DESTINATION "${CMAKE_BINDIR_BASE}")

View File

@@ -0,0 +1,174 @@
//
// Copyright 2013 Pixar
//
// Licensed under the terms set forth in the LICENSE.txt file available at
// https://opensubdiv.org/license.
//
#if __VERSION__ < 420
#define centroid
#endif
layout(std140) uniform Transform {
mat4 ModelViewMatrix;
mat4 ProjectionMatrix;
mat4 ModelViewProjectionMatrix;
};
struct ControlVertex {
vec4 position;
centroid vec4 patchCoord; // u, v, level, faceID
ivec4 ptexInfo; // U offset, V offset, 2^ptexlevel', rotation
ivec3 clipFlag;
};
struct OutputVertex {
vec4 position;
vec3 normal;
centroid vec4 patchCoord; // u, v, level, faceID
centroid vec2 tessCoord; // tesscoord.st
vec3 tangent;
vec3 bitangent;
};
//--------------------------------------------------------------
// Vertex Shader
//--------------------------------------------------------------
#ifdef VERTEX_SHADER
layout (location=0) in vec4 position;
out block {
OutputVertex v;
} outpt;
void main()
{
outpt.v.position = ModelViewMatrix * position;
}
#endif
//--------------------------------------------------------------
// Geometry Shader
//--------------------------------------------------------------
#ifdef GEOMETRY_SHADER
layout(lines_adjacency) in;
#define EDGE_VERTS 4
layout(triangle_strip, max_vertices = EDGE_VERTS) out;
in block {
OutputVertex v;
} inpt[EDGE_VERTS];
out block {
OutputVertex v;
} outpt;
void emit(int index, vec3 normal, vec2 uv)
{
outpt.v.position = inpt[index].v.position;
outpt.v.normal = normal;
outpt.v.tessCoord = uv;
gl_Position = ProjectionMatrix * inpt[index].v.position;
EmitVertex();
}
void main()
{
gl_PrimitiveID = gl_PrimitiveIDIn;
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));
emit(0, n0, vec2(0.0,0.0));
emit(1, n0, vec2(0.0,1.0));
emit(3, n0, vec2(1.0,0.0));
emit(2, n0, vec2(1.0,1.0));
EndPrimitive();
}
#endif
//--------------------------------------------------------------
// Fragment Shader
//--------------------------------------------------------------
#ifdef FRAGMENT_SHADER
in block {
OutputVertex v;
} inpt;
out vec4 outColor;
out vec3 outNormal;
#define NUM_LIGHTS 2
struct LightSource {
vec4 position;
vec4 ambient;
vec4 diffuse;
vec4 specular;
};
layout(std140) uniform Lighting {
LightSource lightSource[NUM_LIGHTS];
};
uniform vec4 diffuseColor = vec4(1);
uniform vec4 ambientColor = vec4(1);
uniform samplerBuffer faceColors;
uniform sampler2D faceTexture;
vec4
lighting(vec4 diffuse, vec3 Peye, vec3 Neye)
{
vec4 color = vec4(0);
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 * ambientColor
+ d * lightSource[i].diffuse * diffuse
+ s * lightSource[i].specular;
}
color.a = 1;
return color;
}
void
main()
{
vec3 N = (gl_FrontFacing ? inpt.v.normal : -inpt.v.normal);
vec4 faceColor = texelFetch(faceColors, gl_PrimitiveID);
vec4 tex = texture(faceTexture, inpt.v.tessCoord);
vec4 Cf = lighting(diffuseColor * faceColor * tex, inpt.v.position.xyz, N);
outColor = Cf;
outNormal = N;
}
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,16 @@
//
// Copyright 2013 Pixar
//
// Licensed under the terms set forth in the LICENSE.txt file available at
// https://opensubdiv.org/license.
//
#ifndef FACE_TEXTURE_H
#define FACE_TEXTURE_H
#define FACE_TEXTURE_WIDTH 128
#define FACE_TEXTURE_HEIGHT 128
extern unsigned char face_texture[];
#endif // FACE_TEXTURE_H

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,155 @@
//
// Copyright 2013 Pixar
//
// Licensed under the terms set forth in the LICENSE.txt file available at
// https://opensubdiv.org/license.
//
#if __VERSION__ < 420
#define centroid
#endif
layout(std140) uniform Transform {
mat4 ModelViewMatrix;
mat4 ProjectionMatrix;
mat4 ModelViewProjectionMatrix;
};
//--------------------------------------------------------------
// Vertex Shader
//--------------------------------------------------------------
#ifdef VERTEX_SHADER
layout (location=0) in vec4 position;
layout (location=1) in vec4 data;
out block {
vec4 position;
vec4 data;
} outpt;
void main()
{
outpt.position = ModelViewMatrix * position;
outpt.data = data;
}
#endif
//--------------------------------------------------------------
// Geometry Shader
//--------------------------------------------------------------
#ifdef GEOMETRY_SHADER
layout(points) in;
#define NVERTS 4
layout(triangle_strip, max_vertices = NVERTS) out;
in block {
vec4 position;
vec4 data;
} inpt[];
out block {
vec4 position;
centroid vec2 uv;
flat int colorId;
} outpt;
void emit(int index, vec2 offset, vec2 uv)
{
outpt.position = inpt[0].position;
outpt.uv = uv;
outpt.colorId = int(inpt[0].data.w);
gl_Position = (ProjectionMatrix * inpt[0].position) + vec4(offset, -0.01, 0.0);
EmitVertex();
}
#define FONT_TEXTURE_WIDTH 128
#define FONT_TEXTURE_HEIGHT 128
#define FONT_TEXTURE_COLUMNS 16
#define FONT_TEXTURE_ROWS 8
#define FONT_CHAR_WIDTH (FONT_TEXTURE_WIDTH/FONT_TEXTURE_COLUMNS)
#define FONT_CHAR_HEIGHT (FONT_TEXTURE_HEIGHT/FONT_TEXTURE_ROWS)
vec2 computeUV( int c )
{
c = c % 0x7f;
return vec2( float(c%FONT_TEXTURE_COLUMNS)/float(FONT_TEXTURE_COLUMNS),
float(c/FONT_TEXTURE_COLUMNS)/float(FONT_TEXTURE_ROWS) );
}
uniform float scale=0.01;
void main()
{
gl_PrimitiveID = gl_PrimitiveIDIn;
vec2 uv = computeUV(int(inpt[0].data.z));
vec2 dim = vec2(1.0/FONT_TEXTURE_COLUMNS,
1.0/FONT_TEXTURE_ROWS);
vec2 ofs = inpt[0].data.xy;
vec4 clipPos = ProjectionMatrix * inpt[0].position;
float s = scale * clipPos.w;
emit(0, s * (vec2( 1.0, -2.0)+ofs), uv + dim);
emit(1, s * (vec2( 1.0, 2.0)+ofs), vec2(uv.x+dim.x, uv.y));
emit(2, s * (vec2(-1.0, -2.0)+ofs), vec2(uv.x, uv.y+dim.y));
emit(3, s * (vec2(-1.0, 2.0)+ofs), uv);
EndPrimitive();
}
#endif
//--------------------------------------------------------------
// Fragment Shader
//--------------------------------------------------------------
#ifdef FRAGMENT_SHADER
in block {
vec4 position;
centroid vec2 uv;
flat int colorId;
} inpt;
uniform sampler2D font;
out vec4 outColor;
out vec3 outNormal;
const vec4 colors[9] = vec4[9](vec4(0.9,0.9,0.9,1.0),
vec4(1.0,0.3,0.3,1.0),
vec4(0.3,1.0,0.3,1.0),
vec4(0.3,0.3,1.0,1.0),
vec4(0.0,1.0,0.0,1.0), // green --- yellow --- red
vec4(0.5,1.0,0.0,1.0),
vec4(1.0,1.0,0.0,1.0),
vec4(1.0,0.5,0.0,1.0),
vec4(1.0,0.0,0.0,1.0));
void main()
{
vec4 bitmap = texture(font, inpt.uv);
if (bitmap.a == 0.0) discard;
outColor = bitmap * colors[inpt.colorId];
outNormal = vec3(0.0,0.0,1.0);
//outColor = vec4(inpt.v.uv,0.0,1.0);
}
#endif

View File

@@ -0,0 +1,198 @@
//
// Copyright 2013 Pixar
//
// Licensed under the terms set forth in the LICENSE.txt file available at
// https://opensubdiv.org/license.
//
#include "glLoader.h"
#include "gl_fontutils.h"
#include <cassert>
#include <cstdlib>
#include <cstring>
//------------------------------------------------------------------------------
GLFont::GLFont(GLuint fontTexture) :
_dirty(false),
_program(0),
_transformBinding(0),
_attrPosition(0),
_attrData(0),
_fontTexture(fontTexture),
_scale(0) {
_chars.reserve(500000);
glGenVertexArrays(1, &_VAO);
glGenBuffers(1, &_EAO);
glGenBuffers(1, &_VBO);
glBindVertexArray(_VAO);
glBindBuffer(GL_ARRAY_BUFFER, _VBO);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _EAO);
glBindVertexArray(0);
}
//------------------------------------------------------------------------------
GLFont::~GLFont() {
glDeleteVertexArrays(1, &_VAO);
glGenBuffers(1, &_VBO);
}
//------------------------------------------------------------------------------
void GLFont::bindProgram() {
static const char *shaderSource =
#include "fontShader.gen.h"
;
// Update and bind transform state
if (! _program) {
_program = glCreateProgram();
static char const versionStr[] = "#version 410\n",
vtxDefineStr[] = "#define VERTEX_SHADER\n",
geoDefineStr[] = "#define GEOMETRY_SHADER\n",
fragDefineStr[] = "#define FRAGMENT_SHADER\n";
std::string vsSrc = std::string(versionStr) + vtxDefineStr + shaderSource,
gsSrc = std::string(versionStr) + geoDefineStr + shaderSource,
fsSrc = std::string(versionStr) + fragDefineStr + shaderSource;
GLuint vertexShader =
GLUtils::CompileShader(GL_VERTEX_SHADER, vsSrc.c_str()),
geometryShader =
GLUtils::CompileShader(GL_GEOMETRY_SHADER, gsSrc.c_str()),
fragmentShader =
GLUtils::CompileShader(GL_FRAGMENT_SHADER, fsSrc.c_str());
glAttachShader(_program, vertexShader);
glAttachShader(_program, geometryShader);
glAttachShader(_program, fragmentShader);
glLinkProgram(_program);
GLint status;
glGetProgramiv(_program, GL_LINK_STATUS, &status);
if (status == GL_FALSE) {
GLint infoLogLength;
glGetProgramiv(_program, GL_INFO_LOG_LENGTH, &infoLogLength);
char *infoLog = new char[infoLogLength];
glGetProgramInfoLog(_program, infoLogLength, NULL, infoLog);
printf("%s\n", infoLog);
delete[] infoLog;
exit(1);
}
}
glUseProgram(_program);
if (! _scale) {
_scale = glGetUniformLocation(_program, "scale");
}
if (! _attrPosition) {
_attrPosition = glGetAttribLocation(_program, "position");
}
if (! _attrData) {
_attrData = glGetAttribLocation(_program, "data");
}
}
//------------------------------------------------------------------------------
void
GLFont::SetFontScale(float scale) {
if (_scale) {
glProgramUniform1f(_program, _scale, scale);
}
}
//------------------------------------------------------------------------------
void
GLFont::Clear() {
_chars.clear();
}
//------------------------------------------------------------------------------
void
GLFont::Print3D(float const pos[3], const char * str, int color) {
int len = (int)strlen(str);
for (int i=0; i<len; ++i) {
GLFont::Char c;
memcpy(&c.pos[0], pos, sizeof(float)*3);
c.ofs[0]=2.0f*i;
c.ofs[1]=0.0f;
c.alpha = (float)str[i];
c.color = (float)color;
_chars.push_back(c);
}
_dirty=true;
}
//------------------------------------------------------------------------------
void GLFont::Draw(GLuint transformUB) {
if ((int)_chars.size()==0) {
return;
}
assert(_VAO && _VBO);
glBindVertexArray(_VAO);
bindProgram();
if (! _transformBinding) {
GLuint uboIndex = glGetUniformBlockIndex(_program, "Transform");
if (uboIndex != GL_INVALID_INDEX)
glUniformBlockBinding(_program, uboIndex, _transformBinding);
}
assert(transformUB);
glBindBufferBase(GL_UNIFORM_BUFFER, _transformBinding, transformUB);
glBindBuffer(GL_ARRAY_BUFFER, _VBO);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _EAO);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, _fontTexture);
if (_dirty) {
// generate element array indices for GL_POINTS
std::vector<int> eao(_chars.size());
for (int i=0; i<(int)_chars.size(); ++i) {
eao[i]=i;
}
glBufferData(GL_ELEMENT_ARRAY_BUFFER, eao.size()*sizeof(int), &eao[0], GL_STATIC_DRAW);
// copy character data to VBO
glBufferData(GL_ARRAY_BUFFER, _chars.size()*sizeof(Char), &_chars[0], GL_STATIC_DRAW);
_dirty=false;
}
glEnableVertexAttribArray(_attrPosition);
glVertexAttribPointer(_attrPosition, 3, GL_FLOAT, GL_FALSE, sizeof(Char), 0);
glEnableVertexAttribArray(_attrData);
glVertexAttribPointer(_attrData, 4, GL_FLOAT, GL_FALSE, sizeof(Char), (void*)12);
glDrawElements(GL_POINTS, (int)_chars.size(), GL_UNSIGNED_INT, 0);
glBindVertexArray(0);
glUseProgram(0);
}
//------------------------------------------------------------------------------

View File

@@ -0,0 +1,61 @@
//
// Copyright 2013 Pixar
//
// Licensed under the terms set forth in the LICENSE.txt file available at
// https://opensubdiv.org/license.
//
#ifndef GL_FONT_UTILS_H
#define GL_FONT_UTILS_H
#include "../common/glUtils.h"
#include <vector>
class GLFont {
public:
GLFont(GLuint fontTexture);
~GLFont();
void Draw(GLuint transforUB);
void Clear();
void Print3D(float const pos[3], const char * str, int color=0);
void SetFontScale(float scale);
struct Char {
float pos[3];
float ofs[2];
float alpha;
float color;
};
std::vector<Char> & GetChars() {
_dirty=true;
return _chars;
}
private:
void bindProgram();
std::vector<Char> _chars;
bool _dirty;
GLuint _program,
_transformBinding,
_attrPosition,
_attrData,
_fontTexture,
_scale,
_VAO,
_EAO,
_VBO;
};
#endif // GL_FONT_UTILS_H

View File

@@ -0,0 +1,957 @@
//
// Copyright 2013 Pixar
//
// Licensed under the terms set forth in the LICENSE.txt file available at
// https://opensubdiv.org/license.
//
#include "glLoader.h"
#include "gl_mesh.h"
#include "gl_fontutils.h"
#include "../common/patchColors.h"
#include <cassert>
#include <cstdlib>
#include <cstring>
//------------------------------------------------------------------------------
// color palettes
static float g_solidColor[4] = {1.0f, 1.0f, 1.0f, 1.0f},
g_ambientColor[4] = {0.1f, 0.1f, 0.1f, 1.0f};
static float g_levelColors[10][4] = {{1.0f, 1.0f, 1.0f},
{1.0f, 1.0f, 0.0f},
{1.0f, 0.5f, 0.0f},
{0.8f, 0.0f, 0.0f},
{0.0f, 1.0f, 0.5f},
{0.0f, 1.0f, 1.0f},
{0.0f, 0.5f, 1.0f},
{0.0f, 0.5f, 0.5f},
{0.5f, 0.0f, 1.0f},
{1.0f, 0.5f, 1.0f}};
static float g_parentTypeColors[4][4] = {{0.9f, 0.9f, 0.9f},
{0.4f, 0.8f, 0.4f},
{0.8f, 0.8f, 0.4f},
{0.8f, 0.4f, 0.4f}};
//------------------------------------------------------------------------------
void
GLMesh::setSolidColor(float * color) {
color[0] = _diffuseColor[0];
color[1] = _diffuseColor[1];
color[2] = _diffuseColor[2];
}
void
GLMesh::setColorByLevel(int level, float * color) {
color[0] = g_levelColors[level][0];
color[1] = g_levelColors[level][1];
color[2] = g_levelColors[level][2];
}
void
GLMesh::setColorBySharpness(float sharpness, float * color) {
// 0.0 2.0 4.0
// green --- yellow --- red
color[0] = std::min(1.0f, sharpness * 0.5f);
color[1] = std::min(1.0f, 2.0f - sharpness * 0.5f);
color[2] = 0;
}
//------------------------------------------------------------------------------
static GLuint g_faceTexture=0;
static GLuint
getFaceTexture() {
#include "face_texture.h"
if (! g_faceTexture) {
glGenTextures(1, &g_faceTexture);
glBindTexture(GL_TEXTURE_2D, g_faceTexture);
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, FACE_TEXTURE_WIDTH,
FACE_TEXTURE_HEIGHT, 0, GL_RGBA, GL_UNSIGNED_BYTE, face_texture);
}
return g_faceTexture;
}
//------------------------------------------------------------------------------
GLMesh::GLMesh() : _TBOfaceColors(0) {
for (int i=0; i<COMP_NUM_COMPONENTS; ++i) {
_VAO[i]=0;
_VBO[i]=0;
_EAO[i]=0;
_numComps[i] = 0;
}
memcpy(_ambientColor, g_ambientColor, sizeof(float)*4);
memcpy(_diffuseColor, g_solidColor, sizeof(float)*4);
}
GLMesh::~GLMesh() {
for (int i=0; i<COMP_NUM_COMPONENTS; ++i) {
if (_VAO[i]) {
glDeleteVertexArrays(1, &_VAO[i]);
}
if (_VBO[i]) {
glDeleteBuffers(1, &_VBO[i]);
}
if (_EAO[i]) {
glDeleteBuffers(1, &_EAO[i]);
}
}
}
//------------------------------------------------------------------------------
void
GLMesh::initializeVertexComponentBuffer(float const * vertData, int nverts) {
std::vector<float> & vbo = _vbo[COMP_VERT];
vbo.resize(nverts * 6);
std::vector<int> & eao = _eao[COMP_VERT];
eao.resize(nverts);
for (int vert=0; vert<nverts; ++vert) {
// copy positions
memcpy(&vbo[vert*6], &vertData[vert*3], 3*sizeof(float));
// populate EAO
eao[vert] = vert;
}
}
//------------------------------------------------------------------------------
void
GLMesh::Initialize(Options /* options */,
int nverts, int nfaces, int * vertsperface, int * faceverts,
float const * vertexData) {
{ // vertex color component ----------------------------
initializeVertexComponentBuffer(vertexData, nverts);
std::vector<float> & vbo = _vbo[COMP_VERT];
for (int vert=0, ofs=3; vert<nverts; ++vert, ofs+=6) {
setSolidColor(&vbo[ofs]);
}
}
{ // edge color component ------------------------------
int nedges = nfaces;
std::vector<float> & vbo = _vbo[COMP_EDGE];
vbo.resize(nedges * 2 * 6);
std::vector<int> & eao = _eao[COMP_EDGE];
eao.resize(nedges*2);
for (int edge=0; edge<nedges; ++edge) {
// edge mode expects faces with 2 verts (aka edges) as input
assert(vertsperface[edge]==2);
eao[edge*2 ] = edge*2;
eao[edge*2+1] = edge*2+1;
int const * verts = &faceverts[edge*2];
float * v0 = &vbo[edge*2*6],
* v1 = v0+6;
// copy position
memcpy(v0, vertexData + verts[0]*3, sizeof(float)*3);
memcpy(v1, vertexData + verts[1]*3, sizeof(float)*3);
// default to solid color
setSolidColor(v0+3);
setSolidColor(v1+3);
}
}
{ // face component ------------------------------------
std::vector<float> & vbo = _vbo[COMP_FACE];
vbo.resize(nverts * 3);
memcpy(&vbo[0], vertexData, nverts*sizeof(float)*3);
int nfaceverts = 0;
for (int i=0; i<nfaces; ++i) {
nfaceverts += vertsperface[i];
}
std::vector<int> & eao = _eao[COMP_FACE];
eao.resize(nfaceverts);
_faceColors.resize(nfaces*4);
int const * fverts = faceverts;
for (int face=0, ofs=0; face<nfaces; ++face) {
int nverts = vertsperface[face];
for (int vert=0; vert<nverts; ++vert) {
eao[ofs++] = fverts[vert];
}
setSolidColor(&_faceColors[face*4]);
fverts += nverts;
}
}
_numComps[COMP_FACE] = (int)_eao[COMP_FACE].size();
_numComps[COMP_EDGE] = (int)_eao[COMP_EDGE].size();
_numComps[COMP_VERT] = (int)_eao[COMP_VERT].size();
InitializeDeviceBuffers();
}
//------------------------------------------------------------------------------
void
GLMesh::Initialize(Options options, TopologyRefiner const & refiner,
PatchTable const * patchTable, float const * vertexData) {
if (patchTable) {
initializeBuffers(options, refiner, *patchTable, vertexData);
} else {
initializeBuffers(options, refiner, vertexData);
}
_numComps[COMP_FACE] = (int)_eao[COMP_FACE].size();
_numComps[COMP_EDGE] = (int)_eao[COMP_EDGE].size();
_numComps[COMP_VERT] = (int)_eao[COMP_VERT].size();
//InitializeDeviceBuffers();
}
//------------------------------------------------------------------------------
void
GLMesh::initializeBuffers(Options options,
TopologyRefiner const & refiner, float const * vertexData) {
typedef OpenSubdiv::Far::ConstIndexArray IndexArray;
int maxlevel = refiner.GetMaxLevel();
OpenSubdiv::Far::TopologyLevel const & refLastLevel = refiner.GetLevel(maxlevel);
int nverts = refLastLevel.GetNumVertices(),
nedges = refLastLevel.GetNumEdges(),
nfaces = refLastLevel.GetNumFaces(),
firstvert = 0;
for (int i=0; i<maxlevel; ++i) {
firstvert += refiner.GetLevel(i).GetNumVertices();
}
float const * vertData = &vertexData[firstvert*3];
{ // vertex color component ----------------------------
initializeVertexComponentBuffer(vertData, nverts);
std::vector<float> & vbo = _vbo[COMP_VERT];
// set colors
if (options.vertColorMode==VERTCOLOR_BY_LEVEL) {
for (int level=0, ofs=3; level<=maxlevel; ++level) {
for (int vert=0; vert<refiner.GetLevel(level).GetNumVertices(); ++vert, ofs+=6) {
setColorByLevel(level, &vbo[ofs]);
}
}
} else if (options.vertColorMode==VERTCOLOR_BY_SHARPNESS) {
for (int vert=0, ofs=3; vert<refLastLevel.GetNumVertices(); ++vert, ofs+=6) {
setColorBySharpness(refLastLevel.GetVertexSharpness(vert), &vbo[ofs]);
}
} else if (options.vertColorMode==VERTCOLOR_BY_PARENT_TYPE) {
int ofs=3;
if (maxlevel>0) {
OpenSubdiv::Far::TopologyLevel const & refPrevLevel = refiner.GetLevel(maxlevel-1);
for (int vert=0; vert<refPrevLevel.GetNumFaces(); ++vert, ofs+=6) {
memcpy(&vbo[ofs], g_parentTypeColors[1], sizeof(float)*3);
}
for (int vert=0; vert<refPrevLevel.GetNumEdges(); ++vert, ofs+=6) {
memcpy(&vbo[ofs], g_parentTypeColors[2], sizeof(float)*3);
}
for (int vert=0; vert<refPrevLevel.GetNumVertices(); ++vert, ofs+=6) {
memcpy(&vbo[ofs], g_parentTypeColors[3], sizeof(float)*3);
}
} else {
for (int vert=0; vert<refLastLevel.GetNumVertices(); ++vert, ofs+=6) {
memcpy(&vbo[ofs], g_parentTypeColors[0], sizeof(float)*3);
}
}
} else {
for (int vert=0, ofs=3; vert<nverts; ++vert) {
setSolidColor(&vbo[ofs+=6]);
}
}
}
{ // edge color component ------------------------------
std::vector<float> & vbo = _vbo[COMP_EDGE];
vbo.resize(nedges * 2 * 6);
std::vector<int> & eao = _eao[COMP_EDGE];
eao.resize(nedges*2);
for (int edge=0; edge<nedges; ++edge) {
eao[edge*2 ] = edge*2;
eao[edge*2+1] = edge*2+1;
IndexArray const verts = refLastLevel.GetEdgeVertices(edge);
float * v0 = &vbo[edge*2*6],
* v1 = v0+6;
// copy position
memcpy(v0, vertData + verts[0]*3, sizeof(float)*3);
memcpy(v1, vertData + verts[1]*3, sizeof(float)*3);
// set colors
if (options.edgeColorMode==EDGECOLOR_BY_LEVEL) {
setColorByLevel(maxlevel, v0+3);
setColorByLevel(maxlevel, v1+3);
} else if (options.edgeColorMode==EDGECOLOR_BY_SHARPNESS) {
float sharpness = refLastLevel.GetEdgeSharpness(edge);
setColorBySharpness(sharpness, v0+3);
setColorBySharpness(sharpness, v1+3);
} else {
// default to solid color
setSolidColor(v0+3);
setSolidColor(v1+3);
}
}
}
{ // face component ------------------------------------
std::vector<float> & vbo = _vbo[COMP_FACE];
vbo.resize(nverts * 3);
memcpy(&vbo[0], vertData, nverts*sizeof(float)*3);
int nfaceverts = refLastLevel.GetNumFaceVertices();
std::vector<int> & eao = _eao[COMP_FACE];
eao.resize(nfaceverts);
_faceColors.resize(nfaces*4);
for (int face=0, ofs=0; face<nfaces; ++face) {
IndexArray fverts = refLastLevel.GetFaceVertices(face);
for (int vert=0; vert<fverts.size(); ++vert) {
eao[ofs++] = fverts[vert];
}
setSolidColor(&_faceColors[face*4]);
}
}
}
//------------------------------------------------------------------------------
inline void
setEdge(std::vector<float> & vbo, int edge, float const * vertData, int v0, int v1, float const * color) {
float * dst0 = &vbo[edge*2*6],
* dst1 = dst0+6;
memcpy(dst0, vertData + (v0*3), sizeof(float)*3);
memcpy(dst1, vertData + (v1*3), sizeof(float)*3);
memcpy(dst0+3, color, sizeof(float)*3);
memcpy(dst1+3, color, sizeof(float)*3);
}
//------------------------------------------------------------------------------
void
GLMesh::InitializeFVar(Options options, TopologyRefiner const & refiner,
PatchTable const * patchTable, int channel, int tessFactor, float const * fvarData) {
int nverts = refiner.GetNumFVarValuesTotal(channel);
{ // vertex color component ----------------------------
initializeVertexComponentBuffer(fvarData, nverts);
std::vector<float> & vbo = _vbo[COMP_VERT];
if (options.vertColorMode==VERTCOLOR_BY_LEVEL) {
for (int level=0, ofs=3; level<=refiner.GetMaxLevel(); ++level) {
for (int vert=0; vert<refiner.GetLevel(level).GetNumFVarValues(channel); ++vert, ofs+=6) {
assert(ofs<(int)vbo.size());
setColorByLevel(level, &vbo[ofs]);
}
}
} else {
for (int vert=0, ofs=3; vert<nverts; ++vert) {
setSolidColor(&vbo[ofs+=6]);
}
}
}
if (tessFactor>0) {
// edge color component ------------------------------
int npatches = patchTable->GetNumPatchesTotal(),
nvertsperpatch = (tessFactor) * (tessFactor),
nedgesperpatch = (tessFactor-1) * (tessFactor*2+tessFactor-1),
//nverts = npatches * nvertsperpatch,
nedges = npatches * nedgesperpatch;
std::vector<float> & vbo = _vbo[COMP_EDGE];
vbo.resize(nedges * 2 * 6);
std::vector<int> & eao = _eao[COMP_EDGE];
eao.reserve(nedges*2);
// default to solid color
static float quadColor[3] = { 1.0f, 1.0f, 0.0f };
float const * color = quadColor;
// wireframe indices
int * basisedges = (int *)alloca(2*nedgesperpatch*sizeof(int)),
* ptr = basisedges;
for (int i=0; i<(tessFactor-1); ++i) { // tess pattern :
for (int j=0; j<(tessFactor-1); ++j) { //
*ptr++ = i*tessFactor + j; // o---o---o--
*ptr++ = i*tessFactor + j+1; // |\ |\ |
// | \ | \ |
*ptr++ = i * tessFactor + j; // | \| \|
*ptr++ = (i+1) * tessFactor + j; // o---o---o--
// |\ |\ |
*ptr++ = i * tessFactor + j; // | \ | \ |
*ptr++ = (i+1) * tessFactor + j+1; // | \| \|
} // o---o---o--
*ptr++ = (i+1) * tessFactor - 1; // | | |
*ptr++ = (i+2) * tessFactor - 1;
*ptr++ = tessFactor * (tessFactor-1) + i;
*ptr++ = tessFactor * (tessFactor-1) + i+1;
}
for (int patch=0, offset=0; patch<npatches; ++patch) {
assert(color);
for (int edge=0; edge<nedgesperpatch; ++edge) {
eao.push_back((int)eao.size());
eao.push_back((int)eao.size());
int v0 = offset + basisedges[edge*2],
v1 = offset + basisedges[edge*2+1];
setEdge(vbo, patch*nedgesperpatch+edge, fvarData, v0, v1, color);
}
offset += nvertsperpatch;
}
}
_numComps[COMP_FACE] = (int)_eao[COMP_FACE].size();
_numComps[COMP_EDGE] = (int)_eao[COMP_EDGE].size();
_numComps[COMP_VERT] = (int)_eao[COMP_VERT].size();
InitializeDeviceBuffers();
}
//------------------------------------------------------------------------------
// returns the number of edges in a patch with 'numCVs'
inline int
getNumEdges(int numCVs) {
switch (numCVs) {
case 4: return 4;
// case 9: return 12;
case 9: return 4;
// case 12: return 17;
case 12: return 4;
// case 16: return 24;
case 16: return 4;
case 20: return 4;
default:
assert(0);
}
return -1;
}
//------------------------------------------------------------------------------
int const *
getEdgeList(int numCVs) {
/*
static int edgeList4[] = { 0, 1, 1, 2, 2, 3, 3, 0 };
static int edgeList9[] = { 0, 1, 1, 4,
3, 2, 2, 5,
8, 7, 7, 6,
0, 3, 3, 8,
1, 2, 2, 7,
4, 5, 5, 6 };
static int edgeList12[] = { 4, 0, 0, 3, 3, 5,
11, 1, 1, 2, 2, 6,
10, 9, 9, 8, 8, 7,
4, 11, 11, 10, 0, 1,
1, 9, 3, 2, 2, 8,
5, 6, 6, 7 };
static int edgeList16[] = { 4, 15, 15, 14, 14, 13,
5, 0, 0, 3, 3, 12,
6, 1, 1, 2, 2, 11,
7, 8, 8, 9, 9, 10,
4, 5, 5, 6, 6, 7,
15, 0, 0, 1, 1, 8,
14, 3, 3, 2, 2, 9,
13, 12, 12, 11, 11, 10 };
*/
static int edgeList4of16[] = { 5, 6, 6, 10, 10, 9, 9, 5 };
static int edgeList4of20[] = { 0, 5, 5, 10, 10, 15, 15, 0 };
switch (numCVs) {
case 4: return edgeList4of20; break;
case 16: return edgeList4of16; break;
case 20: return edgeList4of20; break;
default:
assert(0);
}
return 0;
}
inline int
getRingSize(OpenSubdiv::Far::PatchDescriptor desc) {
if (desc.GetType()==OpenSubdiv::Far::PatchDescriptor::GREGORY_BASIS) {
return 4;
} else {
return desc.GetNumControlVertices();
}
}
//------------------------------------------------------------------------------
void
GLMesh::initializeBuffers(Options options, TopologyRefiner const & refiner,
PatchTable const & patchTable, float const * vertexData) {
int nverts = refiner.GetNumVerticesTotal();
{ // vertex color component ----------------------------
initializeVertexComponentBuffer(vertexData, nverts);
std::vector<float> & vbo = _vbo[COMP_VERT];
if (options.vertColorMode==VERTCOLOR_BY_LEVEL) {
for (int level=0, ofs=3; level<=refiner.GetMaxLevel(); ++level) {
for (int vert=0; vert<refiner.GetLevel(level).GetNumVertices(); ++vert, ofs+=6) {
assert(ofs<(int)vbo.size());
setColorByLevel(level, &vbo[ofs]);
}
}
} else {
for (int vert=0, ofs=3; vert<nverts; ++vert) {
setSolidColor(&vbo[ofs+=6]);
}
}
}
typedef OpenSubdiv::Far::PatchDescriptor Descriptor;
{ // edge color component ------------------------------
int nedges = 0;
for (int array=0; array<(int)patchTable.GetNumPatchArrays(); ++array) {
int ncvs = getRingSize(patchTable.GetPatchArrayDescriptor(array));
nedges += patchTable.GetNumPatches(array) * getNumEdges(ncvs);
}
std::vector<float> & vbo = _vbo[COMP_EDGE];
vbo.resize(nedges * 2 * 6);
std::vector<int> & eao = _eao[COMP_EDGE];
eao.resize(nedges*2);
// default to solid color
float solidColor[3];
setSolidColor(solidColor);
float const * color=solidColor;
for (int array=0, edge=0; array<(int)patchTable.GetNumPatchArrays(); ++array) {
OpenSubdiv::Far::PatchDescriptor desc =
patchTable.GetPatchArrayDescriptor(array);
if (options.edgeColorMode==EDGECOLOR_BY_PATCHTYPE) {
color = getAdaptivePatchColor(desc);
}
int ncvs = getRingSize(desc);
for (int patch=0; patch<patchTable.GetNumPatches(array); ++patch) {
OpenSubdiv::Far::ConstIndexArray const cvs =
patchTable.GetPatchVertices(array, patch);
int const * edgeList=getEdgeList(ncvs);
for (int k=0; k<getNumEdges(cvs.size()); ++k, ++edge) {
eao[edge*2 ] = edge*2;
eao[edge*2+1] = edge*2+1;
int v0 = cvs[edgeList[k*2]],
v1 = cvs[edgeList[k*2+1]];
setEdge(vbo, edge, vertexData, v0, v1, color);
}
}
}
}
{ // face color component ------------------------------
int nfaces = patchTable.GetNumPatchesTotal();
std::vector<float> & vbo = _vbo[COMP_FACE];
vbo.resize(nverts*3);
memcpy(&vbo[0], vertexData, nverts*sizeof(float)*3);
std::vector<int> & eao = _eao[COMP_FACE];
eao.resize(nfaces*4);
_faceColors.resize(nfaces*4, 1.0f);
// default to solid color
for (int array=0, face=0; array<(int)patchTable.GetNumPatchArrays(); ++array) {
OpenSubdiv::Far::PatchDescriptor desc =
patchTable.GetPatchArrayDescriptor(array);
//int ncvs = getRingSize(desc);
for (int patch=0; patch<patchTable.GetNumPatches(array); ++patch, ++face) {
OpenSubdiv::Far::ConstIndexArray const cvs =
patchTable.GetPatchVertices(array, patch);
if (desc.GetType()==Descriptor::REGULAR) {
eao[face*4 ] = cvs[ 5];
eao[face*4+1] = cvs[ 6];
eao[face*4+2] = cvs[10];
eao[face*4+3] = cvs[ 9];
} else {
memcpy(&eao[face*4], cvs.begin(), 4*sizeof(OpenSubdiv::Far::Index));
}
if (options.faceColorMode==FACECOLOR_BY_PATCHTYPE) {
float const * color = getAdaptivePatchColor(desc);
memcpy(&_faceColors[face*4], color, 4*sizeof(float));
} else {
setSolidColor(&_faceColors[face*4]);
}
}
}
}
}
//------------------------------------------------------------------------------
template <typename T> static GLuint
createTextureBuffer(T const &data, GLint format, int offset=0) {
GLuint buffer = 0, texture = 0;
glGenTextures(1, &texture);
glGenBuffers(1, &buffer);
glBindBuffer(GL_ARRAY_BUFFER, buffer);
glBufferData(GL_ARRAY_BUFFER,
(data.size()-offset)*sizeof(typename T::value_type),
&data[offset], GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindTexture(GL_TEXTURE_BUFFER, texture);
glTexBuffer(GL_TEXTURE_BUFFER, format, buffer);
glBindTexture(GL_TEXTURE_BUFFER, 0);
glDeleteBuffers(1, &buffer);
GLUtils::CheckGLErrors("createTextureBuffer");
return texture;
}
//------------------------------------------------------------------------------
void
GLMesh::InitializeDeviceBuffers() {
// copy buffers to device
for (int i=0; i<COMP_NUM_COMPONENTS; ++i) {
if (! _VAO[i]) {
glGenVertexArrays(1, &_VAO[i]);
}
glBindVertexArray(_VAO[i]);
if (! _vbo[i].empty()) {
if (! _VBO[i]) {
glGenBuffers(1, &_VBO[i]);
}
glBindBuffer(GL_ARRAY_BUFFER, _VBO[i]);
glBufferData(GL_ARRAY_BUFFER, _vbo[i].size()*sizeof(GLfloat), &_vbo[i][0], GL_STATIC_DRAW);
glEnableVertexAttribArray(0);
int numelements = (i==COMP_FACE) ? 3 : 6;
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, numelements*sizeof(GLfloat), 0);
if (i==COMP_FACE) {
// face vbo has no color component
glDisableVertexAttribArray(1);
} else {
glEnableVertexAttribArray(1);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6*sizeof(GLfloat), (void*)12);
}
}
if (! _eao[i].empty()) {
if (! _EAO[i]) {
glGenBuffers(1, &_EAO[i]);
}
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _EAO[i]);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, _eao[i].size()*sizeof(int), &_eao[i][0], GL_STATIC_DRAW);
}
GLUtils::CheckGLErrors("init");
}
if (! _faceColors.empty()) {
_TBOfaceColors = createTextureBuffer(_faceColors, GL_RGBA32F);
}
glBindVertexArray(0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
clearBuffers();
}
//------------------------------------------------------------------------------
void
GLMesh::clearBuffers() {
for (int i=0; i<COMP_NUM_COMPONENTS; ++i) {
_vbo[i].clear();
_eao[i].clear();
}
}
//------------------------------------------------------------------------------
static const char * g_simpleShaderSrc =
#include "simpleShader.gen.h"
;
static const char * g_faceShaderSrc =
#include "faceShader.gen.h"
;
GLuint g_simpleProgram=0,
g_faceProgram=0;
// Update and bind transform state
static void
bindProgram( char const * shaderSource,
GLuint * program,
GLuint transformUB,
GLuint lightingUB,
bool geometry) {
assert(program);
GLuint uboIndex=GL_INVALID_INDEX,
transformBinding=0,
lightingBinding=1;
// Update and bind transform state
if (! *program) {
*program = glCreateProgram();
static char const versionStr[] = "#version 330\n",
vtxDefineStr[] = "#define VERTEX_SHADER\n",
geoDefineStr[] = "#define GEOMETRY_SHADER\n",
fragDefineStr[] = "#define FRAGMENT_SHADER\n";
std::string vsSrc = std::string(versionStr) + vtxDefineStr + shaderSource,
gsSrc = std::string(versionStr) + geoDefineStr + shaderSource,
fsSrc = std::string(versionStr) + fragDefineStr + shaderSource;
GLuint vertexShader =
GLUtils::CompileShader(GL_VERTEX_SHADER, vsSrc.c_str()),
geometryShader = geometry ?
GLUtils::CompileShader(GL_GEOMETRY_SHADER, gsSrc.c_str()) : 0,
fragmentShader =
GLUtils::CompileShader(GL_FRAGMENT_SHADER, fsSrc.c_str());
glAttachShader(*program, vertexShader);
if (geometry) {
glAttachShader(*program, geometryShader);
}
glAttachShader(*program, fragmentShader);
glLinkProgram(*program);
GLint status;
glGetProgramiv(*program, GL_LINK_STATUS, &status);
if (status == GL_FALSE) {
GLint infoLogLength;
glGetProgramiv(*program, GL_INFO_LOG_LENGTH, &infoLogLength);
char *infoLog = new char[infoLogLength];
glGetProgramInfoLog(*program, infoLogLength, NULL, infoLog);
printf("%s\n", infoLog);
delete[] infoLog;
exit(1);
}
uboIndex = glGetUniformBlockIndex(*program, "Transform");
if (uboIndex != GL_INVALID_INDEX) {
glUniformBlockBinding(*program, uboIndex, transformBinding);
}
uboIndex = glGetUniformBlockIndex(*program, "Lighting");
if (uboIndex != GL_INVALID_INDEX) {
glUniformBlockBinding(*program, uboIndex, lightingBinding);
}
}
glUseProgram(*program);
if (transformUB) {
glBindBufferBase(GL_UNIFORM_BUFFER, transformBinding, transformUB);
}
if (lightingUB) {
glBindBufferBase(GL_UNIFORM_BUFFER, lightingBinding, lightingUB);
}
}
//------------------------------------------------------------------------------
void
GLMesh::Draw(Component comp, GLuint transformUB, GLuint lightingUB) {
if (comp==COMP_VERT) {
bindProgram(g_simpleShaderSrc, &g_simpleProgram, transformUB, lightingUB, false);
glBindVertexArray(_VAO[COMP_VERT]);
glPointSize(4.0f);
glDrawElements(GL_POINTS, _numComps[COMP_VERT], GL_UNSIGNED_INT, (void *)0);
glPointSize(1.0f);
} else if (comp==COMP_EDGE) {
bindProgram(g_simpleShaderSrc, &g_simpleProgram, transformUB, lightingUB, false);
glBindVertexArray(_VAO[COMP_EDGE]);
glDrawElements(GL_LINES, _numComps[COMP_EDGE], GL_UNSIGNED_INT, (void *)0);
} else if (comp==COMP_FACE) {
glEnable(GL_CULL_FACE);
bindProgram(g_faceShaderSrc, &g_faceProgram, transformUB, lightingUB, true);
{ // set shader parameters
GLuint diffuseColor = glGetUniformLocation(g_faceProgram, "diffuseColor");
glProgramUniform4f(g_faceProgram, diffuseColor, _diffuseColor[0],
_diffuseColor[1], _diffuseColor[2], _diffuseColor[3]);
GLuint faceColors = glGetUniformLocation(g_faceProgram, "faceColors");
glUniform1i(faceColors, 0); // GL_TEXTURE0
GLuint faceTexture = glGetUniformLocation(g_faceProgram, "faceTexture");
glUniform1i(faceTexture, 1); // GL_TEXTURE1
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_BUFFER, _TBOfaceColors);
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, getFaceTexture());
}
glBindVertexArray(_VAO[COMP_FACE]);
glDrawElements(GL_LINES_ADJACENCY, _numComps[COMP_FACE], GL_UNSIGNED_INT, (void *)0);
glDisable(GL_CULL_FACE);
}
}
//------------------------------------------------------------------------------
void
GLMesh::SetDiffuseColor(float r, float g, float b, float a) {
_diffuseColor[0] = r;
_diffuseColor[1] = g;
_diffuseColor[2] = b;
_diffuseColor[3] = a;
}
//------------------------------------------------------------------------------
void
GLMesh::SetFaceColor(int face, float r, float g, float b, float a) {
assert( (face*4) < (int)_faceColors.size() );
float * color = &_faceColors[face*4];
color[0] = r;
color[1] = g;
color[2] = b;
color[3] = a;
}
//------------------------------------------------------------------------------

View File

@@ -0,0 +1,123 @@
//
// Copyright 2013 Pixar
//
// Licensed under the terms set forth in the LICENSE.txt file available at
// https://opensubdiv.org/license.
//
#ifndef GL_MESH_H
#define GL_MESH_H
#include "../../regression/common/far_utils.h"
#include <opensubdiv/far/patchTable.h>
#include "../common/glUtils.h"
#include <algorithm>
// Wrapper class for drawing Far meshes & components
class GLMesh {
public:
enum Component {
COMP_FACE=0,
COMP_EDGE,
COMP_VERT,
COMP_NUM_COMPONENTS
};
enum VertColorMode {
VERTCOLOR_SOLID=0,
VERTCOLOR_BY_LEVEL,
VERTCOLOR_BY_SHARPNESS,
VERTCOLOR_BY_PARENT_TYPE
};
enum EdgeColorMode {
EDGECOLOR_SOLID=0,
EDGECOLOR_BY_LEVEL,
EDGECOLOR_BY_SHARPNESS,
EDGECOLOR_BY_PATCHTYPE
};
enum FaceColorMode {
FACECOLOR_SOLID=0,
FACECOLOR_BY_PATCHTYPE
};
struct Options {
Options() : vertColorMode(0), edgeColorMode(0), faceColorMode(0) {}
unsigned int vertColorMode:3,
edgeColorMode:3,
faceColorMode:3;
};
// -----------------------------------------------------
// Raw topology initialization
void Initialize(Options options,
int nverts, int nfaces, int * vertsperface, int * faceverts,
float const * vertexData);
// -----------------------------------------------------
// Far initialization
typedef OpenSubdiv::Far::TopologyRefiner TopologyRefiner;
typedef OpenSubdiv::Far::PatchTable PatchTable;
void Initialize(Options options, TopologyRefiner const & refiner,
PatchTable const * patchTable, float const * vertexData);
void InitializeFVar(Options options, TopologyRefiner const & refiner,
PatchTable const * patchTable, int channel, int tessFactor, float const * fvarData);
void InitializeDeviceBuffers();
// -----------------------------------------------------
GLMesh();
~GLMesh();
void Draw(Component comp, GLuint transformUB, GLuint lightingUB);
void SetDiffuseColor(float r, float g, float b, float a);
void SetFaceColor(int face, float r, float g, float b, float a);
private:
void setSolidColor(float * color);
static void setColorByLevel(int level, float * color);
static void setColorBySharpness(float sharpness, float * color);
void initializeVertexComponentBuffer(float const * vertexData, int nverts);
void initializeBuffers(Options options, TopologyRefiner const & refiner,
float const * vertexData);
void initializeBuffers(Options options, TopologyRefiner const & refiner,
PatchTable const & patchTable, float const * vertexData);
void clearBuffers();
int _numComps[COMP_NUM_COMPONENTS];
GLuint _VAO[COMP_NUM_COMPONENTS],
_VBO[COMP_NUM_COMPONENTS],
_EAO[COMP_NUM_COMPONENTS],
_TBOfaceColors;
std::vector<float> _vbo[COMP_NUM_COMPONENTS];
std::vector<int> _eao[COMP_NUM_COMPONENTS];
std::vector<float > _faceColors;
float _ambientColor[4],
_diffuseColor[4];
};
#endif // GL_MESH_H

View File

@@ -0,0 +1,74 @@
//
// Copyright 2013 Pixar
//
// Licensed under the terms set forth in the LICENSE.txt file available at
// https://opensubdiv.org/license.
//
#include "../../regression/common/shape_utils.h"
#include "../../regression/shapes/all.h"
static std::vector<ShapeDesc> g_shapes;
//------------------------------------------------------------------------------
static void initShapes() {
// g_shapes.push_back( ShapeDesc("bilinear_cube", bilinear_cube, kBilinear) );
g_shapes.push_back( ShapeDesc("catmark_cube_corner0", catmark_cube_corner0, kCatmark ) );
g_shapes.push_back( ShapeDesc("catmark_cube_corner1", catmark_cube_corner1, kCatmark ) );
g_shapes.push_back( ShapeDesc("catmark_cube_corner2", catmark_cube_corner2, kCatmark ) );
g_shapes.push_back( ShapeDesc("catmark_cube_corner3", catmark_cube_corner3, kCatmark ) );
g_shapes.push_back( ShapeDesc("catmark_cube_corner4", catmark_cube_corner4, kCatmark ) );
g_shapes.push_back( ShapeDesc("catmark_cube_creases0", catmark_cube_creases0, kCatmark ) );
g_shapes.push_back( ShapeDesc("catmark_cube_creases1", catmark_cube_creases1, kCatmark ) );
g_shapes.push_back( ShapeDesc("catmark_cube", catmark_cube, kCatmark ) );
g_shapes.push_back( ShapeDesc("catmark_dart_edgecorner", catmark_dart_edgecorner, kCatmark ) );
g_shapes.push_back( ShapeDesc("catmark_dart_edgeonly", catmark_dart_edgeonly, kCatmark ) );
g_shapes.push_back( ShapeDesc("catmark_chaikin0", catmark_chaikin0, kCatmark ) );
g_shapes.push_back( ShapeDesc("catmark_chaikin1", catmark_chaikin1, kCatmark ) );
g_shapes.push_back( ShapeDesc("catmark_chaikin2", catmark_chaikin2, kCatmark ) );
g_shapes.push_back( ShapeDesc("catmark_edgecorner", catmark_edgecorner, kCatmark ) );
g_shapes.push_back( ShapeDesc("catmark_edgeonly", catmark_edgeonly, kCatmark ) );
g_shapes.push_back( ShapeDesc("catmark_edgenone", catmark_edgenone, kCatmark ) );
g_shapes.push_back( ShapeDesc("catmark_fan", catmark_fan, kCatmark ) );
g_shapes.push_back( ShapeDesc("catmark_flap", catmark_flap, kCatmark ) );
g_shapes.push_back( ShapeDesc("catmark_flap2", catmark_flap2, kCatmark ) );
g_shapes.push_back( ShapeDesc("catmark_fvar_bound0", catmark_fvar_bound0, kCatmark ) );
g_shapes.push_back( ShapeDesc("catmark_fvar_bound1", catmark_fvar_bound1, kCatmark ) );
g_shapes.push_back( ShapeDesc("catmark_fvar_bound2", catmark_fvar_bound2, kCatmark ) );
g_shapes.push_back( ShapeDesc("catmark_gregory_test0", catmark_gregory_test0, kCatmark ) );
g_shapes.push_back( ShapeDesc("catmark_gregory_test1", catmark_gregory_test1, kCatmark ) );
g_shapes.push_back( ShapeDesc("catmark_gregory_test2", catmark_gregory_test2, kCatmark ) );
g_shapes.push_back( ShapeDesc("catmark_gregory_test3", catmark_gregory_test3, kCatmark ) );
g_shapes.push_back( ShapeDesc("catmark_gregory_test4", catmark_gregory_test4, kCatmark ) );
g_shapes.push_back( ShapeDesc("catmark_helmet", catmark_helmet, kCatmark ) );
g_shapes.push_back( ShapeDesc("catmark_pyramid_creases0", catmark_pyramid_creases0, kCatmark ) );
g_shapes.push_back( ShapeDesc("catmark_pyramid_creases1", catmark_pyramid_creases1, kCatmark ) );
g_shapes.push_back( ShapeDesc("catmark_pyramid", catmark_pyramid, kCatmark ) );
// g_shapes.push_back( ShapeDesc("catmark_square_hedit0", catmark_square_hedit0, kCatmark ) );
// g_shapes.push_back( ShapeDesc("catmark_square_hedit1", catmark_square_hedit1, kCatmark ) );
// g_shapes.push_back( ShapeDesc("catmark_square_hedit2", catmark_square_hedit2, kCatmark ) );
// g_shapes.push_back( ShapeDesc("catmark_square_hedit3", catmark_square_hedit3, kCatmark ) );
g_shapes.push_back( ShapeDesc("catmark_tent_creases0", catmark_tent_creases0, kCatmark ) );
g_shapes.push_back( ShapeDesc("catmark_tent_creases1", catmark_tent_creases1 , kCatmark ) );
g_shapes.push_back( ShapeDesc("catmark_tent", catmark_tent, kCatmark ) );
g_shapes.push_back( ShapeDesc("catmark_tent", catmark_tent, kCatmark ) );
g_shapes.push_back( ShapeDesc("catmark_torus", catmark_torus, kCatmark ) );
g_shapes.push_back( ShapeDesc("catmark_torus_creases0", catmark_torus_creases0, kCatmark ) );
g_shapes.push_back( ShapeDesc("catmark_smoothtris0", catmark_smoothtris0, kCatmark ) );
g_shapes.push_back( ShapeDesc("catmark_smoothtris1", catmark_smoothtris1, kCatmark ) );
g_shapes.push_back( ShapeDesc("catmark_car", catmark_car, kCatmark ) );
g_shapes.push_back( ShapeDesc("catmark_bishop", catmark_bishop, kCatmark ) );
// g_shapes.push_back( ShapeDesc("loop_cube_creases0", loop_cube_creases0, kLoop ) );
// g_shapes.push_back( ShapeDesc("loop_cube_creases1", loop_cube_creases1, kLoop ) );
// g_shapes.push_back( ShapeDesc("loop_cube", loop_cube, kLoop ) );
// g_shapes.push_back( ShapeDesc("loop_icosahedron", loop_icosahedron, kLoop ) );
// g_shapes.push_back( ShapeDesc("loop_triangle_edgecorner", loop_triangle_edgecorner, kLoop ) );
// g_shapes.push_back( ShapeDesc("loop_triangle_edgeonly", loop_triangle_edgeonly, kLoop ) );
// g_shapes.push_back( ShapeDesc("loop_triangle_edgenone", loop_triangle_edgenone, kLoop ) );
// g_shapes.push_back( ShapeDesc("loop_chaikin0", loop_chaikin0, kLoop ) );
// g_shapes.push_back( ShapeDesc("loop_chaikin1", loop_chaikin1, kLoop ) );
}
//------------------------------------------------------------------------------

View File

@@ -0,0 +1,44 @@
//
// Copyright 2013 Pixar
//
// Licensed under the terms set forth in the LICENSE.txt file available at
// https://opensubdiv.org/license.
//
layout(std140) uniform Transform {
mat4 ModelViewMatrix;
mat4 ProjectionMatrix;
mat4 ModelViewProjectionMatrix;
};
//--------------------------------------------------------------
// Vertex Shader
//--------------------------------------------------------------
#ifdef VERTEX_SHADER
layout (location=0) in vec3 position;
layout (location=1) in vec3 color;
out vec4 fragColor;
void main()
{
fragColor = vec4(color,1.0);
gl_Position = ModelViewProjectionMatrix * vec4(position, 1);
}
#endif
//--------------------------------------------------------------
// Fragment Shader
//--------------------------------------------------------------
#ifdef FRAGMENT_SHADER
in vec4 fragColor;
out vec4 color;
void main() {
color = fragColor;
}
#endif