Add Chromium-only Blender WebEngine parity work
This commit is contained in:
52
blender-5.2.0/extern/opensubdiv-source/examples/glImaging/CMakeLists.txt
vendored
Normal file
52
blender-5.2.0/extern/opensubdiv-source/examples/glImaging/CMakeLists.txt
vendored
Normal file
@@ -0,0 +1,52 @@
|
||||
#
|
||||
# Copyright 2015 Pixar
|
||||
#
|
||||
# Licensed under the terms set forth in the LICENSE.txt file available at
|
||||
# https://opensubdiv.org/license.
|
||||
#
|
||||
|
||||
# *** glImaging ***
|
||||
|
||||
set(SHADER_FILES
|
||||
shader.glsl
|
||||
)
|
||||
|
||||
include_directories(
|
||||
"${OPENSUBDIV_INCLUDE_DIR}"
|
||||
"${OPENGL_LOADER_INCLUDE_DIRS}"
|
||||
"${GLFW_INCLUDE_DIR}"
|
||||
)
|
||||
|
||||
set(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(glImaging "examples"
|
||||
glImaging.cpp
|
||||
"${SHADER_FILES}"
|
||||
"${INC_FILES}"
|
||||
$<TARGET_OBJECTS:regression_common_obj>
|
||||
$<TARGET_OBJECTS:examples_common_gl_obj>
|
||||
)
|
||||
|
||||
target_link_libraries(glImaging
|
||||
${PLATFORM_LIBRARIES}
|
||||
)
|
||||
|
||||
install(TARGETS glImaging DESTINATION "${CMAKE_BINDIR_BASE}")
|
||||
|
||||
if (NOT NO_GLTESTS)
|
||||
add_test(glImaging ${EXECUTABLE_OUTPUT_PATH}/glImaging -w test -l 3 -s 256 256 -a)
|
||||
endif()
|
||||
|
||||
690
blender-5.2.0/extern/opensubdiv-source/examples/glImaging/glImaging.cpp
vendored
Normal file
690
blender-5.2.0/extern/opensubdiv-source/examples/glImaging/glImaging.cpp
vendored
Normal file
@@ -0,0 +1,690 @@
|
||||
//
|
||||
// Copyright 2015 Pixar
|
||||
//
|
||||
// Licensed under the terms set forth in the LICENSE.txt file available at
|
||||
// https://opensubdiv.org/license.
|
||||
//
|
||||
|
||||
#include "glLoader.h"
|
||||
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <sstream>
|
||||
#include <limits>
|
||||
#include <GLFW/glfw3.h>
|
||||
|
||||
#include <opensubdiv/osd/cpuEvaluator.h>
|
||||
#include <opensubdiv/osd/cpuGLVertexBuffer.h>
|
||||
|
||||
#ifdef OPENSUBDIV_HAS_OPENMP
|
||||
#include <opensubdiv/osd/ompEvaluator.h>
|
||||
#endif
|
||||
|
||||
#ifdef OPENSUBDIV_HAS_TBB
|
||||
#include <opensubdiv/osd/tbbEvaluator.h>
|
||||
#endif
|
||||
|
||||
#ifdef OPENSUBDIV_HAS_OPENCL
|
||||
#include <opensubdiv/osd/clEvaluator.h>
|
||||
#include <opensubdiv/osd/clGLVertexBuffer.h>
|
||||
|
||||
#include "../common/clDeviceContext.h"
|
||||
CLDeviceContext g_clDeviceContext;
|
||||
#endif
|
||||
|
||||
#ifdef OPENSUBDIV_HAS_CUDA
|
||||
#include <opensubdiv/osd/cudaEvaluator.h>
|
||||
#include <opensubdiv/osd/cudaGLVertexBuffer.h>
|
||||
#include "../common/cudaDeviceContext.h"
|
||||
CudaDeviceContext g_cudaDeviceContext;
|
||||
#endif
|
||||
|
||||
#ifdef OPENSUBDIV_HAS_GLSL_TRANSFORM_FEEDBACK
|
||||
#include <opensubdiv/osd/glXFBEvaluator.h>
|
||||
#include <opensubdiv/osd/glVertexBuffer.h>
|
||||
#endif
|
||||
|
||||
#ifdef OPENSUBDIV_HAS_GLSL_COMPUTE
|
||||
#include <opensubdiv/osd/glComputeEvaluator.h>
|
||||
#include <opensubdiv/osd/glVertexBuffer.h>
|
||||
#endif
|
||||
|
||||
#include <opensubdiv/osd/glMesh.h>
|
||||
|
||||
#include "../../regression/common/far_utils.h"
|
||||
#include "../../regression/common/arg_utils.h"
|
||||
#include "../common/patchColors.h"
|
||||
#include "../common/stb_image_write.h" // common.obj has an implementation.
|
||||
#include "../common/glShaderCache.h"
|
||||
#include "../common/glUtils.h"
|
||||
#include "init_shapes.h"
|
||||
|
||||
using namespace OpenSubdiv;
|
||||
|
||||
#include <opensubdiv/osd/glslPatchShaderSource.h>
|
||||
static const char *shaderSource =
|
||||
#include "shader.gen.h"
|
||||
;
|
||||
|
||||
class ShaderCache : public GLShaderCache<OpenSubdiv::Far::PatchDescriptor> {
|
||||
public:
|
||||
ShaderCache(std::string const &displayMode) : _displayMode(displayMode) { }
|
||||
|
||||
virtual GLDrawConfig *CreateDrawConfig(OpenSubdiv::Far::PatchDescriptor const &desc) {
|
||||
|
||||
using namespace OpenSubdiv;
|
||||
|
||||
// compile shader program
|
||||
GLDrawConfig *config =
|
||||
new GLDrawConfig(GLUtils::GetShaderVersionInclude().c_str());
|
||||
|
||||
Far::PatchDescriptor::Type type = desc.GetType();
|
||||
|
||||
// common defines
|
||||
std::stringstream ss;
|
||||
|
||||
if (type == Far::PatchDescriptor::QUADS) {
|
||||
ss << "#define PRIM_QUAD\n";
|
||||
} else {
|
||||
ss << "#define PRIM_TRI\n";
|
||||
}
|
||||
|
||||
// need for patch color-coding : we need these defines in the fragment shader
|
||||
if (type == Far::PatchDescriptor::GREGORY) {
|
||||
ss << "#define OSD_PATCH_GREGORY\n";
|
||||
} else if (type == Far::PatchDescriptor::GREGORY_BOUNDARY) {
|
||||
ss << "#define OSD_PATCH_GREGORY_BOUNDARY\n";
|
||||
} else if (type == Far::PatchDescriptor::GREGORY_BASIS) {
|
||||
ss << "#define OSD_PATCH_GREGORY_BASIS\n";
|
||||
} else if (type == Far::PatchDescriptor::LOOP) {
|
||||
ss << "#define OSD_PATCH_LOOP\n";
|
||||
} else if (type == Far::PatchDescriptor::GREGORY_TRIANGLE) {
|
||||
ss << "#define OSD_PATCH_GREGORY_TRIANGLE\n";
|
||||
}
|
||||
|
||||
if (desc.IsAdaptive()) {
|
||||
ss << "#define SMOOTH_NORMALS\n";
|
||||
}
|
||||
ss << "#define DISPLAY_MODE_" << _displayMode << "\n";
|
||||
ss << "#define OSD_ENABLE_PATCH_CULL\n";
|
||||
ss << "#define GEOMETRY_OUT_LINE\n";
|
||||
|
||||
if (desc.IsAdaptive() && type == Far::PatchDescriptor::REGULAR) {
|
||||
ss << "#define OSD_PATCH_ENABLE_SINGLE_CREASE\n";
|
||||
}
|
||||
|
||||
// include osd PatchCommon
|
||||
ss << Osd::GLSLPatchShaderSource::GetCommonShaderSource();
|
||||
std::string common = ss.str();
|
||||
ss.str("");
|
||||
|
||||
// vertex shader
|
||||
ss << common
|
||||
<< (desc.IsAdaptive() ? "" : "#define VERTEX_SHADER\n") // for my shader source
|
||||
<< shaderSource
|
||||
<< Osd::GLSLPatchShaderSource::GetVertexShaderSource(type);
|
||||
config->CompileAndAttachShader(GL_VERTEX_SHADER, ss.str());
|
||||
ss.str("");
|
||||
|
||||
if (desc.IsAdaptive()) {
|
||||
// tess control shader
|
||||
ss << common
|
||||
<< shaderSource
|
||||
<< Osd::GLSLPatchShaderSource::GetTessControlShaderSource(type);
|
||||
config->CompileAndAttachShader(GL_TESS_CONTROL_SHADER, ss.str());
|
||||
ss.str("");
|
||||
|
||||
// tess eval shader
|
||||
ss << common
|
||||
<< shaderSource
|
||||
<< Osd::GLSLPatchShaderSource::GetTessEvalShaderSource(type);
|
||||
config->CompileAndAttachShader(GL_TESS_EVALUATION_SHADER, ss.str());
|
||||
ss.str("");
|
||||
}
|
||||
|
||||
// geometry shader
|
||||
ss << common
|
||||
<< "#define GEOMETRY_SHADER\n" // for my shader source
|
||||
<< shaderSource;
|
||||
config->CompileAndAttachShader(GL_GEOMETRY_SHADER, ss.str());
|
||||
ss.str("");
|
||||
|
||||
// fragment shader
|
||||
ss << common
|
||||
<< "#define FRAGMENT_SHADER\n" // for my shader source
|
||||
<< shaderSource;
|
||||
config->CompileAndAttachShader(GL_FRAGMENT_SHADER, ss.str());
|
||||
ss.str("");
|
||||
|
||||
if (!config->Link()) {
|
||||
delete config;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// assign uniform locations
|
||||
GLuint uboIndex;
|
||||
GLuint program = config->GetProgram();
|
||||
uboIndex = glGetUniformBlockIndex(program, "Transform");
|
||||
if (uboIndex != GL_INVALID_INDEX)
|
||||
glUniformBlockBinding(program, uboIndex, 0);
|
||||
|
||||
// assign texture locations
|
||||
GLint loc;
|
||||
if ((loc = glGetUniformLocation(program, "OsdPatchParamBuffer")) != -1) {
|
||||
glProgramUniform1i(program, loc, 0); // GL_TEXTURE0
|
||||
}
|
||||
|
||||
return config;
|
||||
}
|
||||
private:
|
||||
std::string _displayMode;
|
||||
};
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
static Osd::GLMeshInterface *
|
||||
createOsdMesh(std::string const &kernel,
|
||||
Far::TopologyRefiner *refiner,
|
||||
int numVertexElements,
|
||||
int numVaryingElements,
|
||||
int level,
|
||||
Osd::MeshBitset bits)
|
||||
{
|
||||
if (kernel == "CPU") {
|
||||
return new Osd::Mesh<Osd::CpuGLVertexBuffer,
|
||||
Far::StencilTable,
|
||||
Osd::CpuEvaluator,
|
||||
Osd::GLPatchTable>(
|
||||
refiner,
|
||||
numVertexElements,
|
||||
numVaryingElements,
|
||||
level, bits);
|
||||
#ifdef OPENSUBDIV_HAS_OPENMP
|
||||
} else if (kernel == "OPENMP") {
|
||||
return new Osd::Mesh<Osd::CpuGLVertexBuffer,
|
||||
Far::StencilTable,
|
||||
Osd::OmpEvaluator,
|
||||
Osd::GLPatchTable>(
|
||||
refiner,
|
||||
numVertexElements,
|
||||
numVaryingElements,
|
||||
level, bits);
|
||||
#endif
|
||||
#ifdef OPENSUBDIV_HAS_TBB
|
||||
} else if (kernel == "TBB") {
|
||||
return new Osd::Mesh<Osd::CpuGLVertexBuffer,
|
||||
Far::StencilTable,
|
||||
Osd::TbbEvaluator,
|
||||
Osd::GLPatchTable>(
|
||||
refiner,
|
||||
numVertexElements,
|
||||
numVaryingElements,
|
||||
level, bits);
|
||||
#endif
|
||||
#ifdef OPENSUBDIV_HAS_OPENCL
|
||||
} else if(kernel == "CL") {
|
||||
return new Osd::Mesh<Osd::CLGLVertexBuffer,
|
||||
Osd::CLStencilTable,
|
||||
Osd::CLEvaluator,
|
||||
Osd::GLPatchTable,
|
||||
CLDeviceContext>(
|
||||
refiner,
|
||||
numVertexElements,
|
||||
numVaryingElements,
|
||||
level, bits,
|
||||
NULL,
|
||||
&g_clDeviceContext);
|
||||
#endif
|
||||
#ifdef OPENSUBDIV_HAS_CUDA
|
||||
} else if(kernel == "CUDA") {
|
||||
return new Osd::Mesh<Osd::CudaGLVertexBuffer,
|
||||
Osd::CudaStencilTable,
|
||||
Osd::CudaEvaluator,
|
||||
Osd::GLPatchTable>(
|
||||
refiner,
|
||||
numVertexElements,
|
||||
numVaryingElements,
|
||||
level, bits);
|
||||
#endif
|
||||
#ifdef OPENSUBDIV_HAS_GLSL_TRANSFORM_FEEDBACK
|
||||
} else if(kernel == "XFB") {
|
||||
return new Osd::Mesh<Osd::GLVertexBuffer,
|
||||
Osd::GLStencilTableTBO,
|
||||
Osd::GLXFBEvaluator,
|
||||
Osd::GLPatchTable>(
|
||||
refiner,
|
||||
numVertexElements,
|
||||
numVaryingElements,
|
||||
level, bits);
|
||||
#endif
|
||||
#ifdef OPENSUBDIV_HAS_GLSL_COMPUTE
|
||||
} else if(kernel == "GLSL") {
|
||||
return new Osd::Mesh<Osd::GLVertexBuffer,
|
||||
Osd::GLStencilTableSSBO,
|
||||
Osd::GLComputeEvaluator,
|
||||
Osd::GLPatchTable>(
|
||||
refiner,
|
||||
numVertexElements,
|
||||
numVaryingElements,
|
||||
level, bits);
|
||||
#endif
|
||||
}
|
||||
|
||||
std::cout << "Specified kernel is not supported in this build.\n";
|
||||
exit(1);
|
||||
}
|
||||
|
||||
void runTest(ShapeDesc const &shapeDesc, std::string const &kernel,
|
||||
int level, bool adaptive,
|
||||
ShaderCache *shaderCache) {
|
||||
|
||||
std::cout << "Testing " << shapeDesc.name << ", kernel = " << kernel << "\n";
|
||||
|
||||
Shape const * shape = Shape::parseObj(shapeDesc);
|
||||
|
||||
// create Far mesh (topology)
|
||||
Sdc::SchemeType sdctype = GetSdcType(*shape);
|
||||
Sdc::Options sdcoptions = GetSdcOptions(*shape);
|
||||
|
||||
// create topology refiner
|
||||
Far::TopologyRefiner *refiner =
|
||||
Far::TopologyRefinerFactory<Shape>::Create(
|
||||
*shape,
|
||||
Far::TopologyRefinerFactory<Shape>::Options(sdctype, sdcoptions));
|
||||
|
||||
bool interleaveVarying = true;
|
||||
bool doSingleCreasePatch = true;
|
||||
|
||||
Osd::MeshBitset bits;
|
||||
bits.set(Osd::MeshAdaptive, adaptive);
|
||||
bits.set(Osd::MeshUseSingleCreasePatch, doSingleCreasePatch);
|
||||
bits.set(Osd::MeshInterleaveVarying, interleaveVarying);
|
||||
bits.set(Osd::MeshFVarData, false);
|
||||
bits.set(Osd::MeshEndCapGregoryBasis, true);
|
||||
|
||||
int numVertexElements = 3 + 4; // XYZ, RGBA (interleaved)
|
||||
int numVaryingElements = 0;
|
||||
|
||||
Osd::GLMeshInterface *mesh = createOsdMesh(
|
||||
kernel, refiner, numVertexElements, numVaryingElements, level, bits);
|
||||
|
||||
int nverts = shape->GetNumVertices();
|
||||
// centering
|
||||
float pmin[3] = { std::numeric_limits<float>::max(),
|
||||
std::numeric_limits<float>::max(),
|
||||
std::numeric_limits<float>::max() };
|
||||
float pmax[3] = { -std::numeric_limits<float>::max(),
|
||||
-std::numeric_limits<float>::max(),
|
||||
-std::numeric_limits<float>::max() };
|
||||
for (int i = 0; i < nverts; ++i) {
|
||||
for (int j = 0; j < 3; ++j) {
|
||||
float v = shape->verts[i*3+j];
|
||||
pmin[j] = std::min(v, pmin[j]);
|
||||
pmax[j] = std::max(v, pmax[j]);
|
||||
}
|
||||
}
|
||||
float center[3] = { (pmax[0]+pmin[0])*0.5f,
|
||||
(pmax[1]+pmin[1])*0.5f,
|
||||
(pmax[2]+pmin[2])*0.5f };
|
||||
float radius = sqrt((pmax[0]-pmin[0])*(pmax[0]-pmin[0]) +
|
||||
(pmax[1]-pmin[1])*(pmax[1]-pmin[1]) +
|
||||
(pmax[2]-pmin[2])*(pmax[2]-pmin[2]));
|
||||
|
||||
// prepare coarse vertices
|
||||
std::vector<float> vertex;
|
||||
vertex.resize(nverts * numVertexElements);
|
||||
for (int i = 0; i < nverts; ++i) {
|
||||
// normalize xyz
|
||||
for (int j = 0; j < 3; ++j) {
|
||||
vertex[i*numVertexElements+j] =
|
||||
(shape->verts[i*3+j] - center[j])/radius;
|
||||
}
|
||||
// set rgb from xyz
|
||||
for (int j = 0; j < 3; ++j) {
|
||||
vertex[i*numVertexElements+j+3] =
|
||||
(shape->verts[i*3+j] - pmin[j])*2.0f/radius;
|
||||
}
|
||||
// set alpha to 1.0
|
||||
vertex[i*numVertexElements+3+3] = 1.0f;
|
||||
}
|
||||
mesh->UpdateVertexBuffer(&vertex[0], 0, nverts);
|
||||
|
||||
// refine
|
||||
mesh->Refine();
|
||||
|
||||
// draw
|
||||
glClearColor(0.1f, 0.1f, 0.1f, 1.0);
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
|
||||
GLuint vao;
|
||||
glGenVertexArrays(1, &vao);
|
||||
glBindVertexArray(vao);
|
||||
|
||||
// bind vertex
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mesh->GetPatchTable()->GetPatchIndexBuffer());
|
||||
glBindBuffer(GL_ARRAY_BUFFER, mesh->BindVertexBuffer());
|
||||
|
||||
glEnableVertexAttribArray(0);
|
||||
glEnableVertexAttribArray(1);
|
||||
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE,
|
||||
sizeof (GLfloat) * numVertexElements, 0);
|
||||
glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE,
|
||||
sizeof (GLfloat) * numVertexElements,
|
||||
(const void*)(sizeof(GLfloat)*3));
|
||||
|
||||
// bind patchparam
|
||||
if (mesh->GetPatchTable()->GetPatchParamTextureBuffer()) {
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
glBindTexture(GL_TEXTURE_BUFFER,
|
||||
mesh->GetPatchTable()->GetPatchParamTextureBuffer());
|
||||
}
|
||||
|
||||
Osd::PatchArrayVector const & patches =
|
||||
mesh->GetPatchTable()->GetPatchArrays();
|
||||
|
||||
for (int i=0; i<(int)patches.size(); ++i) {
|
||||
Osd::PatchArray const & patch = patches[i];
|
||||
Far::PatchDescriptor desc = patch.GetDescriptor();
|
||||
Far::PatchDescriptor::Type patchType = desc.GetType();
|
||||
|
||||
GLenum primType;
|
||||
switch(patchType) {
|
||||
case Far::PatchDescriptor::QUADS:
|
||||
primType = GL_LINES_ADJACENCY;
|
||||
break;
|
||||
case Far::PatchDescriptor::TRIANGLES:
|
||||
primType = GL_TRIANGLES;
|
||||
break;
|
||||
default:
|
||||
primType = GL_PATCHES;
|
||||
glPatchParameteri(GL_PATCH_VERTICES, desc.GetNumControlVertices());
|
||||
}
|
||||
|
||||
GLuint program = shaderCache->GetDrawConfig(desc)->GetProgram();
|
||||
glUseProgram(program);
|
||||
|
||||
GLuint diffuseColor =
|
||||
glGetUniformLocation(program, "diffuseColor");
|
||||
GLuint uniformPrimitiveIdBase =
|
||||
glGetUniformLocation(program, "PrimitiveIdBase");
|
||||
|
||||
if (primType == GL_PATCHES) {
|
||||
float const * color = getAdaptivePatchColor( desc );
|
||||
glProgramUniform4f(program, diffuseColor,
|
||||
color[0], color[1], color[2], color[3]);
|
||||
glProgramUniform1i(program, uniformPrimitiveIdBase,
|
||||
patch.GetPrimitiveIdBase());
|
||||
} else {
|
||||
glProgramUniform4f(program, diffuseColor, 0.4f, 0.4f, 0.8f, 1);
|
||||
}
|
||||
|
||||
glDrawElements(primType,
|
||||
patch.GetNumPatches() * desc.GetNumControlVertices(),
|
||||
GL_UNSIGNED_INT,
|
||||
(void *)(patch.GetIndexBase() * sizeof(unsigned int)));
|
||||
}
|
||||
|
||||
glDisableVertexAttribArray(0);
|
||||
glDisableVertexAttribArray(1);
|
||||
|
||||
glBindVertexArray(0);
|
||||
glDeleteVertexArrays(1, &vao);
|
||||
|
||||
// cleanup
|
||||
delete shape;
|
||||
delete mesh;
|
||||
|
||||
// mesh takes an ownership of topologyRefiner. no need to delete it.
|
||||
}
|
||||
|
||||
static void usage(const char *program) {
|
||||
std::cout
|
||||
<< "Usage: " << program << "\n"
|
||||
<< " -a : adaptive refinement (default)\n"
|
||||
<< " -u : uniform refinement\n"
|
||||
<< " -l <isolation level> : isolation level (default = 2)\n"
|
||||
<< " -t <tess level> : tessellation level (default = 1)\n"
|
||||
<< " -w <prefix> : write images to PNG as\n"
|
||||
<< " <prefix>_<kernel>_modelname.png\n"
|
||||
<< " -s <width> <height> : image size (default = 128 128)\n"
|
||||
<< " -k <kernel>,<kernel>... : kernel types (default = all)\n"
|
||||
<< " kernel = [CPU, OPENMP, TBB, CUDA, CL, XFB, GLSL]\n"
|
||||
<< " -d <displayMode> : display mode\n"
|
||||
<< " displayMode = [PATCH_TYPE, VARYING, NORMAL]\n";
|
||||
}
|
||||
|
||||
int main(int argc, char ** argv) {
|
||||
|
||||
int width = 128;
|
||||
int height = 128;
|
||||
int tessLevel = 1;
|
||||
int isolationLevel = 2;
|
||||
bool writeToFile = false;
|
||||
bool adaptive = true;
|
||||
std::string prefix;
|
||||
std::string displayMode = "PATCH_TYPE";
|
||||
std::vector<std::string> kernels;
|
||||
|
||||
ArgOptions args;
|
||||
|
||||
args.Parse(argc, argv);
|
||||
|
||||
adaptive = args.GetAdaptive();
|
||||
isolationLevel = args.GetLevel();
|
||||
|
||||
// Parse remaining args
|
||||
const std::vector<const char *> &argvRem = args.GetRemainingArgs();
|
||||
for (size_t i = 0; i < argvRem.size(); ++i) {
|
||||
if (!strcmp(argvRem[i], "-k")) {
|
||||
std::stringstream ss(argvRem[++i]);
|
||||
std::string kernel;
|
||||
while(std::getline(ss, kernel, ',')) {
|
||||
kernels.push_back(kernel);
|
||||
}
|
||||
} else if (!strcmp(argvRem[i], "-t")) {
|
||||
tessLevel = atoi(argvRem[++i]);
|
||||
} else if (!strcmp(argvRem[i], "-w")) {
|
||||
writeToFile = true;
|
||||
prefix = argvRem[++i];
|
||||
} else if (!strcmp(argvRem[i], "-s")) {
|
||||
width = atoi(argvRem[++i]);
|
||||
height = atoi(argvRem[++i]);
|
||||
} else if (!strcmp(argvRem[i], "-d")) {
|
||||
displayMode = argvRem[++i];
|
||||
} else {
|
||||
args.PrintUnrecognizedArgWarning(argvRem[i]);
|
||||
usage(argv[0]);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (! glfwInit()) {
|
||||
std::cout << "Failed to initialize GLFW\n";
|
||||
return 1;
|
||||
}
|
||||
|
||||
static const char windowTitle[] =
|
||||
"OpenSubdiv imaging test " OPENSUBDIV_VERSION_STRING;
|
||||
|
||||
GLUtils::SetMinimumGLVersion();
|
||||
|
||||
GLFWwindow *window = glfwCreateWindow(width, height, windowTitle, NULL, NULL);
|
||||
if (! window) {
|
||||
std::cerr << "Failed to create OpenGL context.\n";
|
||||
glfwTerminate();
|
||||
}
|
||||
|
||||
glfwMakeContextCurrent(window);
|
||||
|
||||
GLUtils::InitializeGL();
|
||||
GLUtils::PrintGLVersion();
|
||||
|
||||
// by default, test all available kernels
|
||||
if (kernels.empty()) {
|
||||
kernels.push_back("CPU");
|
||||
#ifdef OPENSUBDIV_HAS_OPENMP
|
||||
kernels.push_back("OPENMP");
|
||||
#endif
|
||||
#ifdef OPENSUBDIV_HAS_TBB
|
||||
kernels.push_back("TBB");
|
||||
#endif
|
||||
#ifdef OPENSUBDIV_HAS_CUDA
|
||||
kernels.push_back("CUDA");
|
||||
#endif
|
||||
#ifdef OPENSUBDIV_HAS_OPENCL
|
||||
kernels.push_back("CL");
|
||||
#endif
|
||||
#ifdef OPENSUBDIV_HAS_GLSL_TRANSFORM_FEEDBACK
|
||||
if (OSD_OPENGL_HAS(VERSION_4_1)) {
|
||||
kernels.push_back("XFB");
|
||||
}
|
||||
#endif
|
||||
#ifdef OPENSUBDIV_HAS_GLSL_COMPUTE
|
||||
if (OSD_OPENGL_HAS(VERSION_4_3)) {
|
||||
kernels.push_back("GLSL");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
initShapes();
|
||||
|
||||
// initialize GL states
|
||||
glViewport(0, 0, width, height);
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
|
||||
// some regression shapes are not visible in this camera
|
||||
// with backface culling.
|
||||
// glEnable(GL_CULL_FACE);
|
||||
|
||||
// transform uniform
|
||||
float modelview[16] = {
|
||||
0.945518f, -0.191364f, 0.263390f, 0.000000f,
|
||||
0.325568f, 0.555762f, -0.764941f, 0.000000f,
|
||||
0.000000f, 0.809017f, 0.587785f, 0.000000f,
|
||||
0.000000f, 0.000000f, -1.500000f, 1.000000f };
|
||||
float projection[16] = {
|
||||
2.414213f, 0.000000f, 0.000000f, 0.000000f,
|
||||
0.000000f, 2.414213f, 0.000000f, 0.000000f,
|
||||
0.000000f, 0.000000f, -1.000000f, -1.000000f,
|
||||
0.000000f, 0.000000f, -0.000200f, 0.000000f
|
||||
};
|
||||
|
||||
struct Transform {
|
||||
float ModelViewMatrix[16];
|
||||
float ProjectionMatrix[16];
|
||||
float Viewport[4];
|
||||
float TessLevel;
|
||||
} transformData;
|
||||
|
||||
memcpy(transformData.ModelViewMatrix, modelview, sizeof(modelview));
|
||||
memcpy(transformData.ProjectionMatrix, projection, sizeof(projection));
|
||||
transformData.Viewport[0] = 0;
|
||||
transformData.Viewport[1] = 0;
|
||||
transformData.Viewport[2] = static_cast<float>(width);
|
||||
transformData.Viewport[3] = static_cast<float>(height);
|
||||
transformData.TessLevel = static_cast<float>(1 << tessLevel);
|
||||
|
||||
GLuint transformUB = 0;
|
||||
glGenBuffers(1, &transformUB);
|
||||
glBindBuffer(GL_UNIFORM_BUFFER, transformUB);
|
||||
glBufferData(GL_UNIFORM_BUFFER, sizeof(transformData),
|
||||
&transformData, GL_STATIC_DRAW);
|
||||
glBindBufferBase(GL_UNIFORM_BUFFER, /*binding=*/0, transformUB);
|
||||
|
||||
// create draw registry;
|
||||
ShaderCache shaderCache(displayMode);
|
||||
|
||||
// write report html
|
||||
if (writeToFile) {
|
||||
std::string reportfile = prefix + ".html";
|
||||
std::ofstream ofs(reportfile.c_str());
|
||||
|
||||
ofs << "<html>\n"
|
||||
<< "<head><style>\n"
|
||||
<< "table { border-collapse:collapse; } "
|
||||
<< "table,th,td {border: 1px solid black} "
|
||||
<< "</style></head>\n";
|
||||
|
||||
ofs << "<body>\n";
|
||||
ofs << "<h3>OpenSubdiv imaging regression test<h3>\n";
|
||||
ofs << "<pre>\n";
|
||||
ofs << "OpenSubdiv : " << OPENSUBDIV_VERSION_STRING << "\n";
|
||||
ofs << "GL Version : " << glGetString(GL_VERSION)
|
||||
<< ", " << glGetString(GL_VENDOR)
|
||||
<< ", " << glGetString(GL_RENDERER)
|
||||
<< "\n";
|
||||
ofs << "Isolation Level : " << isolationLevel << "\n";
|
||||
ofs << "Tess Level : " << tessLevel << "\n";
|
||||
ofs << "Adaptive : " << adaptive << "\n";
|
||||
ofs << "Display Mode : " << displayMode << "\n";
|
||||
ofs << "</pre>\n";
|
||||
|
||||
ofs << "<table>\n";
|
||||
ofs << "<tr>\n";
|
||||
ofs << "<th>Reference<br>(on github. to be updated)</th>\n";
|
||||
for (size_t k = 0; k < kernels.size(); ++k) {
|
||||
ofs << "<th>" << kernels[k] << "</th>\n";
|
||||
}
|
||||
ofs << "</tr>\n";
|
||||
|
||||
for (size_t i = 0; i < g_defaultShapes.size(); ++i) {
|
||||
ofs << "<tr>\n";
|
||||
ofs << "<td>" << g_defaultShapes[i].name << "</td>\n";
|
||||
for (size_t k = 0; k < kernels.size(); ++k) {
|
||||
ofs << "<td>";
|
||||
ofs << "<img src='" << prefix << "_" << kernels[k] << "_" << g_defaultShapes[i].name << ".png'>";
|
||||
ofs << "</td>";
|
||||
}
|
||||
ofs << "</tr>\n";
|
||||
}
|
||||
ofs << "</table>\n";
|
||||
ofs << "</body></html>\n";
|
||||
ofs.close();
|
||||
}
|
||||
|
||||
// run test
|
||||
for (size_t k = 0; k < kernels.size(); ++k) {
|
||||
std::string const &kernel = kernels[k];
|
||||
|
||||
// prep GPU kernel
|
||||
#ifdef OPENSUBDIV_HAS_OPENCL
|
||||
if (kernel == "CL" && CLDeviceContext::HAS_CL_VERSION_1_1()) {
|
||||
if (g_clDeviceContext.IsInitialized() == false) {
|
||||
if (g_clDeviceContext.Initialize() == false) {
|
||||
std::cout << "Error in initializing OpenCL\n";
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#ifdef OPENSUBDIV_HAS_CUDA
|
||||
if (kernel == "CUDA") {
|
||||
if (g_cudaDeviceContext.IsInitialized() == false) {
|
||||
if (g_cudaDeviceContext.Initialize() == false) {
|
||||
std::cout << "Error in initializing Cuda\n";
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
for (size_t i = 0; i < g_defaultShapes.size(); ++i) {
|
||||
// run test
|
||||
runTest(g_defaultShapes[i], kernel, isolationLevel, adaptive, &shaderCache);
|
||||
|
||||
if (writeToFile) {
|
||||
// read back pixels
|
||||
std::vector<unsigned char> data(width*height*3);
|
||||
glReadPixels(0, 0, width, height, GL_RGB, GL_UNSIGNED_BYTE, &data[0]);
|
||||
|
||||
// write image
|
||||
std::string filename = prefix + "_" + kernel + "_" + g_defaultShapes[i].name + ".png";
|
||||
// flip vertical
|
||||
stbi_write_png(filename.c_str(), width, height, 3, &data[width*3*(height-1)], -width*3);
|
||||
}
|
||||
|
||||
glfwSwapBuffers(window);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
82
blender-5.2.0/extern/opensubdiv-source/examples/glImaging/init_shapes.h
vendored
Normal file
82
blender-5.2.0/extern/opensubdiv-source/examples/glImaging/init_shapes.h
vendored
Normal file
@@ -0,0 +1,82 @@
|
||||
//
|
||||
// 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_defaultShapes;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
static void initShapes() {
|
||||
g_defaultShapes.push_back(ShapeDesc("catmark_toroidal_tet", catmark_toroidal_tet, kCatmark));
|
||||
g_defaultShapes.push_back(ShapeDesc("catmark_cube", catmark_cube, kCatmark));
|
||||
g_defaultShapes.push_back(ShapeDesc("catmark_cubes_semisharp", catmark_cubes_semisharp, kCatmark));
|
||||
g_defaultShapes.push_back(ShapeDesc("catmark_cubes_infsharp", catmark_cubes_infsharp, kCatmark));
|
||||
g_defaultShapes.push_back(ShapeDesc("catmark_pyramid", catmark_pyramid, kCatmark));
|
||||
g_defaultShapes.push_back(ShapeDesc("catmark_pyramid_creases0", catmark_pyramid_creases0, kCatmark));
|
||||
g_defaultShapes.push_back(ShapeDesc("catmark_pyramid_creases1", catmark_pyramid_creases1, kCatmark));
|
||||
g_defaultShapes.push_back(ShapeDesc("catmark_torus", catmark_torus, kCatmark));
|
||||
g_defaultShapes.push_back(ShapeDesc("catmark_torus_creases0", catmark_torus_creases0, kCatmark));
|
||||
g_defaultShapes.push_back(ShapeDesc("catmark_torus_creases1", catmark_torus_creases1, kCatmark));
|
||||
g_defaultShapes.push_back(ShapeDesc("catmark_edgecorner", catmark_edgecorner, kCatmark));
|
||||
g_defaultShapes.push_back(ShapeDesc("catmark_edgeonly", catmark_edgeonly, kCatmark));
|
||||
g_defaultShapes.push_back(ShapeDesc("catmark_edgenone", catmark_edgenone, kCatmark));
|
||||
g_defaultShapes.push_back(ShapeDesc("catmark_quadstrips", catmark_quadstrips, kCatmark));
|
||||
g_defaultShapes.push_back(ShapeDesc("catmark_xord_interior", catmark_xord_interior, kCatmark));
|
||||
g_defaultShapes.push_back(ShapeDesc("catmark_xord_boundary", catmark_xord_boundary, kCatmark));
|
||||
g_defaultShapes.push_back(ShapeDesc("catmark_val2_interior", catmark_val2_interior, kCatmark));
|
||||
g_defaultShapes.push_back(ShapeDesc("catmark_nonquads", catmark_nonquads, kCatmark));
|
||||
g_defaultShapes.push_back(ShapeDesc("catmark_single_crease", catmark_single_crease, kCatmark));
|
||||
g_defaultShapes.push_back(ShapeDesc("catmark_inf_crease0", catmark_inf_crease0, kCatmark));
|
||||
g_defaultShapes.push_back(ShapeDesc("catmark_inf_crease1", catmark_inf_crease1, kCatmark));
|
||||
g_defaultShapes.push_back(ShapeDesc("catmark_nonman_verts", catmark_nonman_verts, kCatmark));
|
||||
g_defaultShapes.push_back(ShapeDesc("catmark_nonman_edges", catmark_nonman_edges, kCatmark));
|
||||
g_defaultShapes.push_back(ShapeDesc("catmark_hole_test1", catmark_hole_test1, kCatmark));
|
||||
g_defaultShapes.push_back(ShapeDesc("catmark_hole_test2", catmark_hole_test2, kCatmark));
|
||||
g_defaultShapes.push_back(ShapeDesc("catmark_hole_test3", catmark_hole_test3, kCatmark));
|
||||
g_defaultShapes.push_back(ShapeDesc("catmark_hole_test4", catmark_hole_test4, kCatmark));
|
||||
g_defaultShapes.push_back(ShapeDesc("catmark_chaikin0", catmark_chaikin0, kCatmark));
|
||||
g_defaultShapes.push_back(ShapeDesc("catmark_chaikin1", catmark_chaikin1, kCatmark));
|
||||
g_defaultShapes.push_back(ShapeDesc("catmark_chaikin2", catmark_chaikin2, kCatmark));
|
||||
g_defaultShapes.push_back(ShapeDesc("catmark_smoothtris0", catmark_smoothtris0, kCatmark));
|
||||
g_defaultShapes.push_back(ShapeDesc("catmark_smoothtris1", catmark_smoothtris1, kCatmark));
|
||||
g_defaultShapes.push_back(ShapeDesc("catmark_pole8", catmark_pole8, kCatmark));
|
||||
g_defaultShapes.push_back(ShapeDesc("catmark_pole64", catmark_pole64, kCatmark));
|
||||
g_defaultShapes.push_back(ShapeDesc("catmark_nonman_quadpole64",catmark_nonman_quadpole64,kCatmark));
|
||||
g_defaultShapes.push_back(ShapeDesc("catmark_nonman_edge100", catmark_nonman_edge100, kCatmark));
|
||||
g_defaultShapes.push_back(ShapeDesc("catmark_helmet", catmark_helmet, kCatmark));
|
||||
g_defaultShapes.push_back(ShapeDesc("catmark_bishop", catmark_bishop, kCatmark));
|
||||
g_defaultShapes.push_back(ShapeDesc("catmark_pawn", catmark_pawn, kCatmark));
|
||||
g_defaultShapes.push_back(ShapeDesc("catmark_rook", catmark_rook, kCatmark));
|
||||
g_defaultShapes.push_back(ShapeDesc("catmark_car", catmark_car, kCatmark));
|
||||
|
||||
g_defaultShapes.push_back(ShapeDesc("loop_toroidal_tet", loop_toroidal_tet, kLoop));
|
||||
g_defaultShapes.push_back(ShapeDesc("loop_tetrahedron", loop_tetrahedron, kLoop));
|
||||
g_defaultShapes.push_back(ShapeDesc("loop_cube", loop_cube, kLoop));
|
||||
g_defaultShapes.push_back(ShapeDesc("loop_cubes_semisharp", loop_cubes_semisharp, kLoop));
|
||||
g_defaultShapes.push_back(ShapeDesc("loop_cubes_infsharp", loop_cubes_infsharp, kLoop));
|
||||
g_defaultShapes.push_back(ShapeDesc("loop_cube_asymmetric", loop_cube_asymmetric, kLoop));
|
||||
g_defaultShapes.push_back(ShapeDesc("loop_icosahedron", loop_icosahedron, kLoop));
|
||||
g_defaultShapes.push_back(ShapeDesc("loop_icos_semisharp", loop_icos_semisharp, kLoop));
|
||||
g_defaultShapes.push_back(ShapeDesc("loop_icos_infsharp", loop_icos_infsharp, kLoop));
|
||||
g_defaultShapes.push_back(ShapeDesc("loop_triangle_edgecorner", loop_triangle_edgecorner, kLoop));
|
||||
g_defaultShapes.push_back(ShapeDesc("loop_triangle_edgeonly", loop_triangle_edgeonly, kLoop));
|
||||
g_defaultShapes.push_back(ShapeDesc("loop_triangle_edgenone", loop_triangle_edgenone, kLoop));
|
||||
g_defaultShapes.push_back(ShapeDesc("loop_xord_interior", loop_xord_interior, kLoop));
|
||||
g_defaultShapes.push_back(ShapeDesc("loop_xord_boundary", loop_xord_boundary, kLoop));
|
||||
g_defaultShapes.push_back(ShapeDesc("loop_nonman_verts", loop_nonman_verts, kLoop));
|
||||
g_defaultShapes.push_back(ShapeDesc("loop_nonman_edges", loop_nonman_edges, kLoop));
|
||||
g_defaultShapes.push_back(ShapeDesc("loop_pole64", loop_pole64, kLoop));
|
||||
g_defaultShapes.push_back(ShapeDesc("loop_nonman_edge100", loop_nonman_edge100, kLoop));
|
||||
|
||||
g_defaultShapes.push_back(ShapeDesc("bilinear_cube", bilinear_cube, kBilinear));
|
||||
g_defaultShapes.push_back(ShapeDesc("bilinear_nonplanar", bilinear_nonplanar, kBilinear));
|
||||
g_defaultShapes.push_back(ShapeDesc("bilinear_nonquads0", bilinear_nonquads0, kBilinear));
|
||||
g_defaultShapes.push_back(ShapeDesc("bilinear_nonquads1", bilinear_nonquads1, kBilinear));
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
425
blender-5.2.0/extern/opensubdiv-source/examples/glImaging/shader.glsl
vendored
Normal file
425
blender-5.2.0/extern/opensubdiv-source/examples/glImaging/shader.glsl
vendored
Normal file
@@ -0,0 +1,425 @@
|
||||
//
|
||||
// Copyright 2013 Pixar
|
||||
//
|
||||
// Licensed under the terms set forth in the LICENSE.txt file available at
|
||||
// https://opensubdiv.org/license.
|
||||
//
|
||||
|
||||
#undef OSD_USER_VARYING_DECLARE
|
||||
#define OSD_USER_VARYING_DECLARE \
|
||||
vec3 color;
|
||||
|
||||
#undef OSD_USER_VARYING_ATTRIBUTE_DECLARE
|
||||
#define OSD_USER_VARYING_ATTRIBUTE_DECLARE \
|
||||
layout(location = 1) in vec3 color;
|
||||
|
||||
#undef OSD_USER_VARYING_PER_VERTEX
|
||||
#define OSD_USER_VARYING_PER_VERTEX() \
|
||||
outpt.color = color
|
||||
|
||||
#undef OSD_USER_VARYING_PER_CONTROL_POINT
|
||||
#define OSD_USER_VARYING_PER_CONTROL_POINT(ID_OUT, ID_IN) \
|
||||
outpt[ID_OUT].color = inpt[ID_IN].color
|
||||
|
||||
#undef OSD_USER_VARYING_PER_EVAL_POINT
|
||||
#define OSD_USER_VARYING_PER_EVAL_POINT(UV, a, b, c, d) \
|
||||
outpt.color = \
|
||||
mix(mix(inpt[a].color, inpt[b].color, UV.x), \
|
||||
mix(inpt[c].color, inpt[d].color, UV.x), UV.y)
|
||||
|
||||
#undef OSD_USER_VARYING_PER_EVAL_POINT_TRIANGLE
|
||||
#define OSD_USER_VARYING_PER_EVAL_POINT_TRIANGLE(UV, a, b, c) \
|
||||
outpt.color = \
|
||||
inpt[a].color * (1.0f - UV.x - UV.y) + \
|
||||
inpt[b].color * UV.x + \
|
||||
inpt[c].color * UV.y;
|
||||
|
||||
//--------------------------------------------------------------
|
||||
// Uniforms / Uniform Blocks
|
||||
//--------------------------------------------------------------
|
||||
|
||||
layout(std140) uniform Transform {
|
||||
mat4 ModelViewMatrix;
|
||||
mat4 ProjectionMatrix;
|
||||
vec4 Viewport;
|
||||
float TessLevel;
|
||||
};
|
||||
|
||||
uniform int GregoryQuadOffsetBase;
|
||||
uniform int PrimitiveIdBase;
|
||||
|
||||
//--------------------------------------------------------------
|
||||
// Osd external functions
|
||||
//--------------------------------------------------------------
|
||||
|
||||
mat4 OsdModelViewMatrix()
|
||||
{
|
||||
return ModelViewMatrix;
|
||||
}
|
||||
mat4 OsdProjectionMatrix()
|
||||
{
|
||||
return ProjectionMatrix;
|
||||
}
|
||||
mat4 OsdModelViewProjectionMatrix()
|
||||
{
|
||||
return OsdProjectionMatrix() * OsdModelViewMatrix();
|
||||
}
|
||||
float OsdTessLevel()
|
||||
{
|
||||
return TessLevel;
|
||||
}
|
||||
int OsdGregoryQuadOffsetBase()
|
||||
{
|
||||
return GregoryQuadOffsetBase;
|
||||
}
|
||||
int OsdPrimitiveIdBase()
|
||||
{
|
||||
return PrimitiveIdBase;
|
||||
}
|
||||
int OsdBaseVertex()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------
|
||||
// Vertex Shader
|
||||
//--------------------------------------------------------------
|
||||
#ifdef VERTEX_SHADER
|
||||
|
||||
layout (location=0) in vec4 position;
|
||||
OSD_USER_VARYING_ATTRIBUTE_DECLARE
|
||||
|
||||
out block {
|
||||
OutputVertex v;
|
||||
OSD_USER_VARYING_DECLARE
|
||||
} outpt;
|
||||
|
||||
void main()
|
||||
{
|
||||
outpt.v.position = ModelViewMatrix * position;
|
||||
outpt.v.patchCoord = vec4(0);
|
||||
OSD_USER_VARYING_PER_VERTEX();
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
//--------------------------------------------------------------
|
||||
// Geometry Shader
|
||||
//--------------------------------------------------------------
|
||||
#ifdef GEOMETRY_SHADER
|
||||
|
||||
#ifdef PRIM_QUAD
|
||||
|
||||
layout(lines_adjacency) in;
|
||||
|
||||
#define EDGE_VERTS 4
|
||||
|
||||
#endif // PRIM_QUAD
|
||||
|
||||
#ifdef PRIM_TRI
|
||||
|
||||
layout(triangles) in;
|
||||
|
||||
#define EDGE_VERTS 3
|
||||
|
||||
#endif // PRIM_TRI
|
||||
|
||||
|
||||
layout(triangle_strip, max_vertices = EDGE_VERTS) out;
|
||||
in block {
|
||||
OutputVertex v;
|
||||
#if defined OSD_PATCH_ENABLE_SINGLE_CREASE
|
||||
vec2 vSegments;
|
||||
#endif
|
||||
OSD_USER_VARYING_DECLARE
|
||||
} inpt[EDGE_VERTS];
|
||||
|
||||
out block {
|
||||
OutputVertex v;
|
||||
noperspective out vec4 edgeDistance;
|
||||
#if defined OSD_PATCH_ENABLE_SINGLE_CREASE
|
||||
vec2 vSegments;
|
||||
#endif
|
||||
OSD_USER_VARYING_DECLARE
|
||||
} outpt;
|
||||
|
||||
void emit(int index, vec3 normal)
|
||||
{
|
||||
outpt.v.position = inpt[index].v.position;
|
||||
outpt.v.patchCoord = inpt[index].v.patchCoord;
|
||||
#ifdef SMOOTH_NORMALS
|
||||
outpt.v.normal = inpt[index].v.normal;
|
||||
#else
|
||||
outpt.v.normal = normal;
|
||||
#endif
|
||||
|
||||
#if defined OSD_PATCH_ENABLE_SINGLE_CREASE
|
||||
outpt.vSegments = inpt[index].vSegments;
|
||||
#endif
|
||||
|
||||
outpt.color = inpt[index].color;
|
||||
|
||||
gl_Position = ProjectionMatrix * inpt[index].v.position;
|
||||
EmitVertex();
|
||||
}
|
||||
|
||||
#if defined(GEOMETRY_OUT_WIRE) || defined(GEOMETRY_OUT_LINE)
|
||||
uniform float viewportScale;
|
||||
|
||||
float edgeDistance(vec4 p, vec4 p0, vec4 p1)
|
||||
{
|
||||
vec4 viewportScale = vec4(0.5*Viewport[2],
|
||||
0.5*Viewport[3],
|
||||
1, 1);
|
||||
p *= viewportScale;
|
||||
p0 *= viewportScale;
|
||||
p1 *= viewportScale;
|
||||
|
||||
return abs((p.x - p0.x) * (p1.y - p0.y) -
|
||||
(p.y - p0.y) * (p1.x - p0.x)) / length(p1.xy - p0.xy);
|
||||
}
|
||||
|
||||
void emit(int index, vec3 normal, vec4 edgeVerts[EDGE_VERTS])
|
||||
{
|
||||
outpt.edgeDistance[0] =
|
||||
edgeDistance(edgeVerts[index], edgeVerts[0], edgeVerts[1]);
|
||||
outpt.edgeDistance[1] =
|
||||
edgeDistance(edgeVerts[index], edgeVerts[1], edgeVerts[2]);
|
||||
#ifdef PRIM_TRI
|
||||
outpt.edgeDistance[2] =
|
||||
outpt.edgeDistance[3] =
|
||||
edgeDistance(edgeVerts[index], edgeVerts[2], edgeVerts[0]);
|
||||
#endif
|
||||
#ifdef PRIM_QUAD
|
||||
outpt.edgeDistance[2] =
|
||||
edgeDistance(edgeVerts[index], edgeVerts[2], edgeVerts[3]);
|
||||
outpt.edgeDistance[3] =
|
||||
edgeDistance(edgeVerts[index], edgeVerts[3], edgeVerts[0]);
|
||||
#endif
|
||||
|
||||
emit(index, normal);
|
||||
}
|
||||
#endif
|
||||
|
||||
void main()
|
||||
{
|
||||
gl_PrimitiveID = gl_PrimitiveIDIn;
|
||||
|
||||
#ifdef PRIM_QUAD
|
||||
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 * 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;
|
||||
edgeVerts[2].xy /= edgeVerts[2].w;
|
||||
edgeVerts[3].xy /= edgeVerts[3].w;
|
||||
|
||||
emit(0, n0, edgeVerts);
|
||||
emit(1, n0, edgeVerts);
|
||||
emit(3, n0, edgeVerts);
|
||||
emit(2, n0, edgeVerts);
|
||||
#else
|
||||
emit(0, n0);
|
||||
emit(1, n0);
|
||||
emit(3, n0);
|
||||
emit(2, n0);
|
||||
#endif
|
||||
#endif // PRIM_QUAD
|
||||
|
||||
#ifdef PRIM_TRI
|
||||
vec3 A = (inpt[0].v.position - inpt[1].v.position).xyz;
|
||||
vec3 B = (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 * 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;
|
||||
edgeVerts[2].xy /= edgeVerts[2].w;
|
||||
|
||||
emit(0, n0, edgeVerts);
|
||||
emit(1, n0, edgeVerts);
|
||||
emit(2, n0, edgeVerts);
|
||||
#else
|
||||
emit(0, n0);
|
||||
emit(1, n0);
|
||||
emit(2, n0);
|
||||
#endif
|
||||
#endif // PRIM_TRI
|
||||
|
||||
EndPrimitive();
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
//--------------------------------------------------------------
|
||||
// Fragment Shader
|
||||
//--------------------------------------------------------------
|
||||
#ifdef FRAGMENT_SHADER
|
||||
|
||||
in block {
|
||||
OutputVertex v;
|
||||
noperspective in vec4 edgeDistance;
|
||||
#if defined OSD_PATCH_ENABLE_SINGLE_CREASE
|
||||
vec2 vSegments;
|
||||
#endif
|
||||
OSD_USER_VARYING_DECLARE
|
||||
} inpt;
|
||||
|
||||
out vec4 outColor;
|
||||
|
||||
uniform vec4 diffuseColor = vec4(1);
|
||||
uniform vec4 ambientColor = vec4(1);
|
||||
|
||||
vec4
|
||||
getAdaptivePatchColor(ivec3 patchParam)
|
||||
{
|
||||
const vec4 patchColors[7*6] = vec4[7*6](
|
||||
vec4(1.0f, 1.0f, 1.0f, 1.0f), // regular
|
||||
vec4(0.0f, 1.0f, 1.0f, 1.0f), // regular pattern 0
|
||||
vec4(0.0f, 0.5f, 1.0f, 1.0f), // regular pattern 1
|
||||
vec4(0.0f, 0.5f, 0.5f, 1.0f), // regular pattern 2
|
||||
vec4(0.5f, 0.0f, 1.0f, 1.0f), // regular pattern 3
|
||||
vec4(1.0f, 0.5f, 1.0f, 1.0f), // regular pattern 4
|
||||
|
||||
vec4(1.0f, 0.5f, 0.5f, 1.0f), // single crease
|
||||
vec4(1.0f, 0.70f, 0.6f, 1.0f), // single crease pattern 0
|
||||
vec4(1.0f, 0.65f, 0.6f, 1.0f), // single crease pattern 1
|
||||
vec4(1.0f, 0.60f, 0.6f, 1.0f), // single crease pattern 2
|
||||
vec4(1.0f, 0.55f, 0.6f, 1.0f), // single crease pattern 3
|
||||
vec4(1.0f, 0.50f, 0.6f, 1.0f), // single crease pattern 4
|
||||
|
||||
vec4(0.8f, 0.0f, 0.0f, 1.0f), // boundary
|
||||
vec4(0.0f, 0.0f, 0.75f, 1.0f), // boundary pattern 0
|
||||
vec4(0.0f, 0.2f, 0.75f, 1.0f), // boundary pattern 1
|
||||
vec4(0.0f, 0.4f, 0.75f, 1.0f), // boundary pattern 2
|
||||
vec4(0.0f, 0.6f, 0.75f, 1.0f), // boundary pattern 3
|
||||
vec4(0.0f, 0.8f, 0.75f, 1.0f), // boundary pattern 4
|
||||
|
||||
vec4(0.0f, 1.0f, 0.0f, 1.0f), // corner
|
||||
vec4(0.5f, 1.0f, 0.5f, 1.0f), // corner pattern 0
|
||||
vec4(0.5f, 1.0f, 0.5f, 1.0f), // corner pattern 1
|
||||
vec4(0.5f, 1.0f, 0.5f, 1.0f), // corner pattern 2
|
||||
vec4(0.5f, 1.0f, 0.5f, 1.0f), // corner pattern 3
|
||||
vec4(0.5f, 1.0f, 0.5f, 1.0f), // corner pattern 4
|
||||
|
||||
vec4(1.0f, 1.0f, 0.0f, 1.0f), // gregory
|
||||
vec4(1.0f, 1.0f, 0.0f, 1.0f), // gregory
|
||||
vec4(1.0f, 1.0f, 0.0f, 1.0f), // gregory
|
||||
vec4(1.0f, 1.0f, 0.0f, 1.0f), // gregory
|
||||
vec4(1.0f, 1.0f, 0.0f, 1.0f), // gregory
|
||||
vec4(1.0f, 1.0f, 0.0f, 1.0f), // gregory
|
||||
|
||||
vec4(1.0f, 0.5f, 0.0f, 1.0f), // gregory boundary
|
||||
vec4(1.0f, 0.5f, 0.0f, 1.0f), // gregory boundary
|
||||
vec4(1.0f, 0.5f, 0.0f, 1.0f), // gregory boundary
|
||||
vec4(1.0f, 0.5f, 0.0f, 1.0f), // gregory boundary
|
||||
vec4(1.0f, 0.5f, 0.0f, 1.0f), // gregory boundary
|
||||
vec4(1.0f, 0.5f, 0.0f, 1.0f), // gregory boundary
|
||||
|
||||
vec4(1.0f, 0.7f, 0.3f, 1.0f), // gregory basis
|
||||
vec4(1.0f, 0.7f, 0.3f, 1.0f), // gregory basis
|
||||
vec4(1.0f, 0.7f, 0.3f, 1.0f), // gregory basis
|
||||
vec4(1.0f, 0.7f, 0.3f, 1.0f), // gregory basis
|
||||
vec4(1.0f, 0.7f, 0.3f, 1.0f), // gregory basis
|
||||
vec4(1.0f, 0.7f, 0.3f, 1.0f) // gregory basis
|
||||
);
|
||||
|
||||
int patchType = 0;
|
||||
|
||||
int edgeCount = bitCount(OsdGetPatchBoundaryMask(patchParam));
|
||||
if (edgeCount == 1) {
|
||||
patchType = 2; // BOUNDARY
|
||||
}
|
||||
if (edgeCount > 1) {
|
||||
patchType = 3; // CORNER (not correct for patches that are not isolated)
|
||||
}
|
||||
|
||||
#if defined OSD_PATCH_ENABLE_SINGLE_CREASE
|
||||
// check this after boundary/corner since single crease patch also has edgeCount.
|
||||
if (inpt.vSegments.y > 0) {
|
||||
patchType = 1;
|
||||
}
|
||||
#elif defined OSD_PATCH_GREGORY
|
||||
patchType = 4;
|
||||
#elif defined OSD_PATCH_GREGORY_BOUNDARY
|
||||
patchType = 5;
|
||||
#elif defined OSD_PATCH_GREGORY_BASIS
|
||||
patchType = 6;
|
||||
#elif defined OSD_PATCH_GREGORY_TRIANGLE
|
||||
patchType = 6;
|
||||
#endif
|
||||
|
||||
int pattern = bitCount(OsdGetPatchTransitionMask(patchParam));
|
||||
|
||||
return patchColors[6*patchType + pattern];
|
||||
}
|
||||
|
||||
|
||||
vec4
|
||||
edgeColor(vec4 Cfill, vec4 edgeDistance)
|
||||
{
|
||||
#if defined(GEOMETRY_OUT_WIRE) || defined(GEOMETRY_OUT_LINE)
|
||||
#ifdef PRIM_TRI
|
||||
float d =
|
||||
min(inpt.edgeDistance[0], min(inpt.edgeDistance[1], inpt.edgeDistance[2]));
|
||||
#endif
|
||||
#ifdef PRIM_QUAD
|
||||
float d =
|
||||
min(min(inpt.edgeDistance[0], inpt.edgeDistance[1]),
|
||||
min(inpt.edgeDistance[2], inpt.edgeDistance[3]));
|
||||
#endif
|
||||
float v = 0.8;
|
||||
vec4 Cedge = vec4(Cfill.r*v, Cfill.g*v, Cfill.b*v, 1);
|
||||
float p = exp2(-2 * d * d);
|
||||
|
||||
#if defined(GEOMETRY_OUT_WIRE)
|
||||
if (p < 0.25) discard;
|
||||
#endif
|
||||
|
||||
Cfill.rgb = mix(Cfill.rgb, Cedge.rgb, p);
|
||||
#endif
|
||||
return Cfill;
|
||||
}
|
||||
|
||||
#if defined(PRIM_QUAD) || defined(PRIM_TRI)
|
||||
void
|
||||
main()
|
||||
{
|
||||
vec3 N = (gl_FrontFacing ? inpt.v.normal : -inpt.v.normal);
|
||||
float d = dot(N, vec3(0,0,1));
|
||||
|
||||
#if defined(DISPLAY_MODE_VARYING)
|
||||
vec4 color = vec4(inpt.color, 1);
|
||||
#else
|
||||
vec4 color = getAdaptivePatchColor(OsdGetPatchParam(OsdGetPatchIndex(gl_PrimitiveID)));
|
||||
#endif
|
||||
|
||||
vec4 Cf = color * d;
|
||||
#if defined(GEOMETRY_OUT_WIRE) || defined(GEOMETRY_OUT_LINE)
|
||||
Cf = edgeColor(Cf, inpt.edgeDistance);
|
||||
#endif
|
||||
|
||||
#if defined(DISPLAY_MODE_NORMAL)
|
||||
outColor = vec4(N.x, N.y, N.z, 1);
|
||||
return;
|
||||
#endif
|
||||
|
||||
outColor = Cf;
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user