OpenSubdiv: Cleanyp, remove old GPU code

All parts of drawing (shaders, GL mesh descriptor, material partitioner
and so on) needs to be redone for the draw manager and new OpenSubdiv
library.

Removing untested code which is doomed to be replaced to make localized
refactoring easier.
This commit is contained in:
Sergey Sharybin 2020-05-18 16:45:14 +02:00
parent 22f68f85a4
commit 2ad5131f77
14 changed files with 0 additions and 1680 deletions

View File

@ -31,7 +31,6 @@ set(SRC
opensubdiv_capi_type.h
opensubdiv_converter_capi.h
opensubdiv_evaluator_capi.h
opensubdiv_gl_mesh_capi.h
opensubdiv_topology_refiner_capi.h
)
@ -58,10 +57,6 @@ if(WITH_OPENSUBDIV)
internal/opensubdiv_device_context_opencl.cc
internal/opensubdiv_evaluator.cc
internal/opensubdiv_evaluator_internal.cc
internal/opensubdiv_gl_mesh.cc
internal/opensubdiv_gl_mesh_draw.cc
internal/opensubdiv_gl_mesh_fvar.cc
internal/opensubdiv_gl_mesh_internal.cc
internal/opensubdiv_topology_refiner.cc
internal/opensubdiv_topology_refiner_internal.cc
internal/opensubdiv_util.cc
@ -72,9 +67,6 @@ if(WITH_OPENSUBDIV)
internal/opensubdiv_device_context_opencl.h
internal/opensubdiv_edge_map.h
internal/opensubdiv_evaluator_internal.h
internal/opensubdiv_gl_mesh_draw.h
internal/opensubdiv_gl_mesh_fvar.h
internal/opensubdiv_gl_mesh_internal.h
internal/opensubdiv_internal.h
internal/opensubdiv_topology_refiner_internal.h
internal/opensubdiv_util.h
@ -98,10 +90,6 @@ if(WITH_OPENSUBDIV)
OPENSUBDIV_DEFINE_COMPONENT(OPENSUBDIV_HAS_GLSL_TRANSFORM_FEEDBACK)
OPENSUBDIV_DEFINE_COMPONENT(OPENSUBDIV_HAS_GLSL_COMPUTE)
data_to_c_simple(shader/gpu_shader_opensubdiv_vertex.glsl SRC)
data_to_c_simple(shader/gpu_shader_opensubdiv_geometry.glsl SRC)
data_to_c_simple(shader/gpu_shader_opensubdiv_fragment.glsl SRC)
add_definitions(-DGLEW_STATIC)
add_definitions(-DOSD_USES_GLEW)
@ -128,7 +116,6 @@ else()
list(APPEND SRC
stub/opensubdiv_stub.cc
stub/opensubdiv_evaluator_stub.cc
stub/opensubdiv_gl_mesh_stub.cc
stub/opensubdiv_topology_refiner_stub.cc
)
endif()

View File

@ -24,7 +24,6 @@
#include "opensubdiv_device_context_cuda.h"
#include "opensubdiv_device_context_opencl.h"
#include "opensubdiv_gl_mesh_capi.h"
void openSubdiv_init(void)
{
@ -34,7 +33,6 @@ void openSubdiv_init(void)
void openSubdiv_cleanup(void)
{
openSubdiv_deinitGLMeshDrawingResources();
}
int openSubdiv_getAvailableEvaluators(void)

View File

@ -1,260 +0,0 @@
// Copyright 2013 Blender Foundation. All rights reserved.
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software Foundation,
// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#include "opensubdiv_gl_mesh_capi.h"
#ifdef _MSC_VER
# include <iso646.h>
#endif
#include <opensubdiv/far/stencilTable.h>
#include <opensubdiv/osd/glMesh.h>
#include <opensubdiv/osd/glPatchTable.h>
using OpenSubdiv::Far::StencilTable;
using OpenSubdiv::Osd::GLMeshInterface;
using OpenSubdiv::Osd::GLPatchTable;
using OpenSubdiv::Osd::Mesh;
using OpenSubdiv::Osd::MeshBitset;
// CPU backend.
#include <opensubdiv/osd/cpuEvaluator.h>
#include <opensubdiv/osd/cpuGLVertexBuffer.h>
using OpenSubdiv::Osd::CpuEvaluator;
using OpenSubdiv::Osd::CpuGLVertexBuffer;
typedef Mesh<CpuGLVertexBuffer, StencilTable, CpuEvaluator, GLPatchTable> OsdCpuMesh;
// OpenMP backend.
#ifdef OPENSUBDIV_HAS_OPENMP
# include <opensubdiv/osd/ompEvaluator.h>
using OpenSubdiv::Osd::OmpEvaluator;
typedef Mesh<CpuGLVertexBuffer, StencilTable, OmpEvaluator, GLPatchTable> OsdOmpMesh;
#endif
// OpenCL backend.
#ifdef OPENSUBDIV_HAS_OPENCL
# include "opensubdiv_device_context_opencl.h"
# include <opensubdiv/osd/clEvaluator.h>
# include <opensubdiv/osd/clGLVertexBuffer.h>
using OpenSubdiv::Osd::CLEvaluator;
using OpenSubdiv::Osd::CLGLVertexBuffer;
using OpenSubdiv::Osd::CLStencilTable;
/* TODO(sergey): Use CLDeviceContext similar to OSD examples? */
typedef Mesh<CLGLVertexBuffer, CLStencilTable, CLEvaluator, GLPatchTable, CLDeviceContext>
OsdCLMesh;
static CLDeviceContext g_cl_device_context;
#endif
// CUDA backend.
#ifdef OPENSUBDIV_HAS_CUDA
# include "opensubdiv_device_context_cuda.h"
# include <opensubdiv/osd/cudaEvaluator.h>
# include <opensubdiv/osd/cudaGLVertexBuffer.h>
using OpenSubdiv::Osd::CudaEvaluator;
using OpenSubdiv::Osd::CudaGLVertexBuffer;
using OpenSubdiv::Osd::CudaStencilTable;
typedef Mesh<CudaGLVertexBuffer, CudaStencilTable, CudaEvaluator, GLPatchTable> OsdCudaMesh;
static CudaDeviceContext g_cuda_device_context;
#endif
// Transform feedback backend.
#ifdef OPENSUBDIV_HAS_GLSL_TRANSFORM_FEEDBACK
# include <opensubdiv/osd/glVertexBuffer.h>
# include <opensubdiv/osd/glXFBEvaluator.h>
using OpenSubdiv::Osd::GLStencilTableTBO;
using OpenSubdiv::Osd::GLVertexBuffer;
using OpenSubdiv::Osd::GLXFBEvaluator;
typedef Mesh<GLVertexBuffer, GLStencilTableTBO, GLXFBEvaluator, GLPatchTable>
OsdGLSLTransformFeedbackMesh;
#endif
// GLSL compute backend.
#ifdef OPENSUBDIV_HAS_GLSL_COMPUTE
# include <opensubdiv/osd/glComputeEvaluator.h>
# include <opensubdiv/osd/glVertexBuffer.h>
using OpenSubdiv::Osd::GLComputeEvaluator;
using OpenSubdiv::Osd::GLStencilTableSSBO;
using OpenSubdiv::Osd::GLVertexBuffer;
typedef Mesh<GLVertexBuffer, GLStencilTableSSBO, GLComputeEvaluator, GLPatchTable>
OsdGLSLComputeMesh;
#endif
#include "MEM_guardedalloc.h"
#include "internal/opensubdiv_gl_mesh_draw.h"
#include "internal/opensubdiv_gl_mesh_fvar.h"
#include "internal/opensubdiv_gl_mesh_internal.h"
#include "internal/opensubdiv_topology_refiner_internal.h"
#include "internal/opensubdiv_util.h"
#include "opensubdiv_topology_refiner_capi.h"
using opensubdiv_capi::vector;
namespace {
GLMeshInterface *createGLMeshInterface(OpenSubdiv::Far::TopologyRefiner *topology_refiner,
const MeshBitset &bits,
const int num_vertex_elements,
const int num_varying_elements,
const int level,
eOpenSubdivEvaluator evaluator_type)
{
GLMeshInterface *mesh = NULL;
switch (evaluator_type) {
#define CHECK_EVALUATOR_TYPE(type, class) \
case OPENSUBDIV_EVALUATOR_##type: \
mesh = new class(topology_refiner, num_vertex_elements, num_varying_elements, level, bits); \
break;
#define CHECK_EVALUATOR_TYPE_STUB(type) \
case OPENSUBDIV_EVALUATOR_##type: \
mesh = NULL; \
break;
CHECK_EVALUATOR_TYPE(CPU, OsdCpuMesh)
#ifdef OPENSUBDIV_HAS_OPENMP
CHECK_EVALUATOR_TYPE(OPENMP, OsdOmpMesh)
#else
CHECK_EVALUATOR_TYPE_STUB(OPENMP)
#endif
#ifdef OPENSUBDIV_HAS_OPENCL
CHECK_EVALUATOR_TYPE(OPENCL, OsdCLMesh)
#else
CHECK_EVALUATOR_TYPE_STUB(OPENCL)
#endif
#ifdef OPENSUBDIV_HAS_CUDA
CHECK_EVALUATOR_TYPE(CUDA, OsdCudaMesh)
#else
CHECK_EVALUATOR_TYPE_STUB(CUDA)
#endif
#ifdef OPENSUBDIV_HAS_GLSL_TRANSFORM_FEEDBACK
CHECK_EVALUATOR_TYPE(GLSL_TRANSFORM_FEEDBACK, OsdGLSLTransformFeedbackMesh)
#else
CHECK_EVALUATOR_TYPE_STUB(GLSL_TRANSFORM_FEEDBACK)
#endif
#ifdef OPENSUBDIV_HAS_GLSL_COMPUTE
CHECK_EVALUATOR_TYPE(GLSL_COMPUTE, OsdGLSLComputeMesh)
#else
CHECK_EVALUATOR_TYPE_STUB(GLSL_COMPUTE)
#endif
#undef CHECK_EVALUATOR_TYPE
#undef CHECK_EVALUATOR_TYPE_STUB
}
return mesh;
}
////////////////////////////////////////////////////////////////////////////////
// GLMesh structure "methods".
opensubdiv_capi::GLMeshFVarData *createFVarData(OpenSubdiv::Far::TopologyRefiner *topology_refiner,
GLMeshInterface *mesh,
const float *fvar_src_buffer)
{
using opensubdiv_capi::GLMeshFVarData;
GLMeshFVarData *fvar_data = new GLMeshFVarData();
fvar_data->create(topology_refiner, mesh->GetFarPatchTable(), 2, fvar_src_buffer);
return fvar_data;
}
unsigned int getPatchIndexBuffer(OpenSubdiv_GLMesh *gl_mesh)
{
return gl_mesh->internal->mesh_interface->GetPatchTable()->GetPatchIndexBuffer();
}
void bindVertexBuffer(OpenSubdiv_GLMesh *gl_mesh)
{
gl_mesh->internal->mesh_interface->BindVertexBuffer();
}
void setCoarsePositions(OpenSubdiv_GLMesh *gl_mesh,
const float *positions,
const int start_vertex,
const int num_vertices)
{
gl_mesh->internal->mesh_interface->UpdateVertexBuffer(positions, start_vertex, num_vertices);
}
void refine(OpenSubdiv_GLMesh *gl_mesh)
{
gl_mesh->internal->mesh_interface->Refine();
}
void synchronize(struct OpenSubdiv_GLMesh *gl_mesh)
{
gl_mesh->internal->mesh_interface->Synchronize();
}
void assignFunctionPointers(OpenSubdiv_GLMesh *gl_mesh)
{
gl_mesh->getPatchIndexBuffer = getPatchIndexBuffer;
gl_mesh->bindVertexBuffer = bindVertexBuffer;
gl_mesh->setCoarsePositions = setCoarsePositions;
gl_mesh->refine = refine;
gl_mesh->synchronize = synchronize;
gl_mesh->prepareDraw = opensubdiv_capi::GLMeshDisplayPrepare;
gl_mesh->drawPatches = opensubdiv_capi::GLMeshDisplayDrawPatches;
}
} // namespace
struct OpenSubdiv_GLMesh *openSubdiv_createOsdGLMeshFromTopologyRefiner(
OpenSubdiv_TopologyRefiner *topology_refiner, eOpenSubdivEvaluator evaluator_type)
{
using OpenSubdiv::Far::TopologyRefiner;
TopologyRefiner *osd_topology_refiner = topology_refiner->internal->osd_topology_refiner;
// TODO(sergey): Query this from refiner.
const bool is_adaptive = false;
MeshBitset bits;
bits.set(OpenSubdiv::Osd::MeshAdaptive, is_adaptive);
bits.set(OpenSubdiv::Osd::MeshUseSingleCreasePatch, 0);
bits.set(OpenSubdiv::Osd::MeshInterleaveVarying, 1);
bits.set(OpenSubdiv::Osd::MeshFVarData, 1);
bits.set(OpenSubdiv::Osd::MeshEndCapBSplineBasis, 1);
const int num_vertex_elements = 3;
const int num_varying_elements = 3;
GLMeshInterface *mesh = createGLMeshInterface(osd_topology_refiner,
bits,
num_vertex_elements,
num_varying_elements,
osd_topology_refiner->GetMaxLevel(),
evaluator_type);
if (mesh == NULL) {
return NULL;
}
OpenSubdiv_GLMesh *gl_mesh = OBJECT_GUARDED_NEW(OpenSubdiv_GLMesh);
assignFunctionPointers(gl_mesh);
gl_mesh->internal = new OpenSubdiv_GLMeshInternal();
gl_mesh->internal->evaluator_type = evaluator_type;
gl_mesh->internal->mesh_interface = mesh;
// Face-varying support.
// TODO(sergey): This part needs to be re-done.
if (osd_topology_refiner->GetNumFVarChannels() > 0) {
// TODO(sergey): This is a temporary stub to get things compiled. Need
// to store base level UVs somewhere else.
vector<float> uvs;
vector<float> fvar_data_buffer;
opensubdiv_capi::interpolateFVarData(*osd_topology_refiner, uvs, &fvar_data_buffer);
gl_mesh->internal->fvar_data = createFVarData(
osd_topology_refiner, mesh, &fvar_data_buffer[0]);
}
else {
gl_mesh->internal->fvar_data = NULL;
}
return gl_mesh;
}
void openSubdiv_deleteOsdGLMesh(OpenSubdiv_GLMesh *gl_mesh)
{
delete gl_mesh->internal;
OBJECT_GUARDED_DELETE(gl_mesh, OpenSubdiv_GLMesh);
}

View File

@ -1,577 +0,0 @@
// Copyright 2013 Blender Foundation. All rights reserved.
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software Foundation,
// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
//
// Author: Sergey Sharybin
#include "internal/opensubdiv_gl_mesh_draw.h"
#ifdef _MSC_VER
# include <iso646.h>
#endif
#include <GL/glew.h>
#include <cmath>
#include <cstdio>
#include <opensubdiv/osd/glMesh.h>
#ifdef OPENSUBDIV_HAS_CUDA
# include <opensubdiv/osd/cudaGLVertexBuffer.h>
#endif // OPENSUBDIV_HAS_CUDA
#include <opensubdiv/osd/cpuEvaluator.h>
#include <opensubdiv/osd/cpuGLVertexBuffer.h>
#include "internal/opensubdiv_gl_mesh_fvar.h"
#include "internal/opensubdiv_gl_mesh_internal.h"
#include "internal/opensubdiv_util.h"
#include "opensubdiv_capi.h"
#include "opensubdiv_gl_mesh_capi.h"
using OpenSubdiv::Osd::GLMeshInterface;
extern "C" char datatoc_gpu_shader_opensubdiv_vertex_glsl[];
extern "C" char datatoc_gpu_shader_opensubdiv_geometry_glsl[];
extern "C" char datatoc_gpu_shader_opensubdiv_fragment_glsl[];
// TODO(sergey): Those are a bit of bad level calls :S
extern "C" {
void copy_m3_m3(float m1[3][3], float m2[3][3]);
void copy_m3_m4(float m1[3][3], float m2[4][4]);
void adjoint_m3_m3(float m1[3][3], float m[3][3]);
float determinant_m3_array(float m[3][3]);
bool invert_m3_m3(float m1[3][3], float m2[3][3]);
bool invert_m3(float m[3][3]);
void transpose_m3(float mat[3][3]);
}
#define MAX_LIGHTS 8
#define SUPPORT_COLOR_MATERIAL
typedef struct Light {
float position[4];
float ambient[4];
float diffuse[4];
float specular[4];
float spot_direction[4];
#ifdef SUPPORT_COLOR_MATERIAL
float constant_attenuation;
float linear_attenuation;
float quadratic_attenuation;
float spot_cutoff;
float spot_exponent;
float spot_cos_cutoff;
float pad, pad2;
#endif
} Light;
typedef struct Lighting {
Light lights[MAX_LIGHTS];
int num_enabled;
} Lighting;
typedef struct Transform {
float projection_matrix[16];
float model_view_matrix[16];
float normal_matrix[9];
} Transform;
static bool g_use_osd_glsl = false;
static int g_active_uv_index = 0;
static GLuint g_flat_fill_solid_program = 0;
static GLuint g_flat_fill_texture2d_program = 0;
static GLuint g_smooth_fill_solid_program = 0;
static GLuint g_smooth_fill_texture2d_program = 0;
static GLuint g_flat_fill_solid_shadeless_program = 0;
static GLuint g_flat_fill_texture2d_shadeless_program = 0;
static GLuint g_smooth_fill_solid_shadeless_program = 0;
static GLuint g_smooth_fill_texture2d_shadeless_program = 0;
static GLuint g_wireframe_program = 0;
static GLuint g_lighting_ub = 0;
static Lighting g_lighting_data;
static Transform g_transform;
namespace {
GLuint compileShader(GLenum shaderType,
const char *version,
const char *define,
const char *source)
{
const char *sources[] = {
version,
define,
#ifdef SUPPORT_COLOR_MATERIAL
"#define SUPPORT_COLOR_MATERIAL\n",
#else
"",
#endif
source,
};
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: %s\n", emsg);
fprintf(stderr, "Version: %s\n", version);
fprintf(stderr, "Defines: %s\n", define);
fprintf(stderr, "Source: %s\n", source);
return 0;
}
return shader;
}
GLuint linkProgram(const char *version, const char *define)
{
GLuint vertexShader = compileShader(
GL_VERTEX_SHADER, version, define, datatoc_gpu_shader_opensubdiv_vertex_glsl);
if (vertexShader == 0) {
return 0;
}
GLuint geometryShader = compileShader(
GL_GEOMETRY_SHADER, version, define, datatoc_gpu_shader_opensubdiv_geometry_glsl);
if (geometryShader == 0) {
return 0;
}
GLuint fragmentShader = compileShader(
GL_FRAGMENT_SHADER, version, define, datatoc_gpu_shader_opensubdiv_fragment_glsl);
if (fragmentShader == 0) {
return 0;
}
GLuint program = glCreateProgram();
glAttachShader(program, vertexShader);
glAttachShader(program, geometryShader);
glAttachShader(program, fragmentShader);
glBindAttribLocation(program, 0, "position");
glBindAttribLocation(program, 1, "normal");
glLinkProgram(program);
glDeleteShader(vertexShader);
glDeleteShader(geometryShader);
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);
glDeleteProgram(program);
return 0;
}
glUniformBlockBinding(program, glGetUniformBlockIndex(program, "Lighting"), 0);
if (GLEW_VERSION_4_1) {
glProgramUniform1i(program, glGetUniformLocation(program, "texture_buffer"), 0);
glProgramUniform1i(program, glGetUniformLocation(program, "FVarDataOffsetBuffer"), 30);
glProgramUniform1i(program, glGetUniformLocation(program, "FVarDataBuffer"), 31);
}
else {
glUseProgram(program);
glUniform1i(glGetUniformLocation(program, "texture_buffer"), 0);
glUniform1i(glGetUniformLocation(program, "FVarDataOffsetBuffer"), 30);
glUniform1i(glGetUniformLocation(program, "FVarDataBuffer"), 31);
glUseProgram(0);
}
return program;
}
void bindProgram(OpenSubdiv_GLMesh *gl_mesh, int program)
{
glUseProgram(program);
// Matrices
glUniformMatrix4fv(
glGetUniformLocation(program, "modelViewMatrix"), 1, false, g_transform.model_view_matrix);
glUniformMatrix4fv(
glGetUniformLocation(program, "projectionMatrix"), 1, false, g_transform.projection_matrix);
glUniformMatrix3fv(
glGetUniformLocation(program, "normalMatrix"), 1, false, g_transform.normal_matrix);
// Lighting.
glBindBuffer(GL_UNIFORM_BUFFER, g_lighting_ub);
glBufferSubData(GL_UNIFORM_BUFFER, 0, sizeof(g_lighting_data), &g_lighting_data);
glBindBuffer(GL_UNIFORM_BUFFER, 0);
glBindBufferBase(GL_UNIFORM_BUFFER, 0, g_lighting_ub);
// Color.
{
// TODO(sergey): Stop using glGetMaterial.
float color[4];
glGetMaterialfv(GL_FRONT, GL_DIFFUSE, color);
glUniform4fv(glGetUniformLocation(program, "diffuse"), 1, color);
glGetMaterialfv(GL_FRONT, GL_SPECULAR, color);
glUniform4fv(glGetUniformLocation(program, "specular"), 1, color);
glGetMaterialfv(GL_FRONT, GL_SHININESS, color);
glUniform1f(glGetUniformLocation(program, "shininess"), color[0]);
}
// Face-vertex data.
opensubdiv_capi::GLMeshFVarData *fvar_data = gl_mesh->internal->fvar_data;
if (fvar_data != NULL) {
if (fvar_data->texture_buffer) {
glActiveTexture(GL_TEXTURE31);
glBindTexture(GL_TEXTURE_BUFFER, fvar_data->texture_buffer);
glActiveTexture(GL_TEXTURE0);
}
if (fvar_data->offset_buffer) {
glActiveTexture(GL_TEXTURE30);
glBindTexture(GL_TEXTURE_BUFFER, fvar_data->offset_buffer);
glActiveTexture(GL_TEXTURE0);
}
glUniform1i(glGetUniformLocation(program, "osd_fvar_count"), fvar_data->fvar_width);
if (fvar_data->channel_offsets.size() > 0 && g_active_uv_index >= 0) {
glUniform1i(glGetUniformLocation(program, "osd_active_uv_offset"),
fvar_data->channel_offsets[g_active_uv_index]);
}
else {
glUniform1i(glGetUniformLocation(program, "osd_active_uv_offset"), 0);
}
}
else {
glUniform1i(glGetUniformLocation(program, "osd_fvar_count"), 0);
glUniform1i(glGetUniformLocation(program, "osd_active_uv_offset"), 0);
}
}
} // namespace
bool openSubdiv_initGLMeshDrawingResources(void)
{
static bool need_init = true;
static bool init_success = false;
if (!need_init) {
return init_success;
}
// TODO(sergey): Update OSD drawing to OpenGL 3.3 core,
// then remove following line.
return false;
const char *version = "";
if (GLEW_VERSION_3_2) {
version = "#version 150 compatibility\n";
}
else if (GLEW_VERSION_3_1) {
version =
"#version 140\n"
"#extension GL_ARB_compatibility: enable\n";
}
else {
version = "#version 130\n";
// Minimum supported for OpenSubdiv.
}
g_flat_fill_solid_program = linkProgram(version,
"#define USE_COLOR_MATERIAL\n"
"#define USE_LIGHTING\n"
"#define FLAT_SHADING\n");
g_flat_fill_texture2d_program = linkProgram(version,
"#define USE_COLOR_MATERIAL\n"
"#define USE_LIGHTING\n"
"#define USE_TEXTURE_2D\n"
"#define FLAT_SHADING\n");
g_smooth_fill_solid_program = linkProgram(version,
"#define USE_COLOR_MATERIAL\n"
"#define USE_LIGHTING\n"
"#define SMOOTH_SHADING\n");
g_smooth_fill_texture2d_program = linkProgram(version,
"#define USE_COLOR_MATERIAL\n"
"#define USE_LIGHTING\n"
"#define USE_TEXTURE_2D\n"
"#define SMOOTH_SHADING\n");
g_flat_fill_solid_shadeless_program = linkProgram(version,
"#define USE_COLOR_MATERIAL\n"
"#define FLAT_SHADING\n");
g_flat_fill_texture2d_shadeless_program = linkProgram(version,
"#define USE_COLOR_MATERIAL\n"
"#define USE_TEXTURE_2D\n"
"#define FLAT_SHADING\n");
g_smooth_fill_solid_shadeless_program = linkProgram(version,
"#define USE_COLOR_MATERIAL\n"
"#define SMOOTH_SHADING\n");
g_smooth_fill_texture2d_shadeless_program = linkProgram(version,
"#define USE_COLOR_MATERIAL\n"
"#define USE_TEXTURE_2D\n"
"#define SMOOTH_SHADING\n");
g_wireframe_program = linkProgram(version, "#define WIREFRAME\n");
glGenBuffers(1, &g_lighting_ub);
glBindBuffer(GL_UNIFORM_BUFFER, g_lighting_ub);
glBufferData(GL_UNIFORM_BUFFER, sizeof(g_lighting_data), NULL, GL_STATIC_DRAW);
need_init = false;
init_success = g_flat_fill_solid_program != 0 && g_flat_fill_texture2d_program != 0 &&
g_smooth_fill_solid_program != 0 && g_smooth_fill_texture2d_program != 0 &&
g_wireframe_program;
return init_success;
}
void openSubdiv_deinitGLMeshDrawingResources(void)
{
if (g_lighting_ub != 0) {
glDeleteBuffers(1, &g_lighting_ub);
}
#define SAFE_DELETE_PROGRAM(program) \
do { \
if (program) { \
glDeleteProgram(program); \
} \
} while (false)
SAFE_DELETE_PROGRAM(g_flat_fill_solid_program);
SAFE_DELETE_PROGRAM(g_flat_fill_texture2d_program);
SAFE_DELETE_PROGRAM(g_smooth_fill_solid_program);
SAFE_DELETE_PROGRAM(g_smooth_fill_texture2d_program);
SAFE_DELETE_PROGRAM(g_flat_fill_solid_shadeless_program);
SAFE_DELETE_PROGRAM(g_flat_fill_texture2d_shadeless_program);
SAFE_DELETE_PROGRAM(g_smooth_fill_solid_shadeless_program);
SAFE_DELETE_PROGRAM(g_smooth_fill_texture2d_shadeless_program);
SAFE_DELETE_PROGRAM(g_wireframe_program);
#undef SAFE_DELETE_PROGRAM
}
namespace opensubdiv_capi {
namespace {
GLuint prepare_patchDraw(OpenSubdiv_GLMesh *gl_mesh, bool fill_quads)
{
GLint program = 0;
if (!g_use_osd_glsl) {
glGetIntegerv(GL_CURRENT_PROGRAM, &program);
if (program) {
GLint model;
glGetIntegerv(GL_SHADE_MODEL, &model);
GLint location = glGetUniformLocation(program, "osd_flat_shading");
if (location != -1) {
glUniform1i(location, model == GL_FLAT);
}
// Face-vertex data.
opensubdiv_capi::GLMeshFVarData *fvar_data = gl_mesh->internal->fvar_data;
if (fvar_data != NULL) {
if (fvar_data->texture_buffer) {
glActiveTexture(GL_TEXTURE31);
glBindTexture(GL_TEXTURE_BUFFER, fvar_data->texture_buffer);
glActiveTexture(GL_TEXTURE0);
}
if (fvar_data->offset_buffer) {
glActiveTexture(GL_TEXTURE30);
glBindTexture(GL_TEXTURE_BUFFER, fvar_data->offset_buffer);
glActiveTexture(GL_TEXTURE0);
}
GLint location = glGetUniformLocation(program, "osd_fvar_count");
if (location != -1) {
glUniform1i(location, fvar_data->fvar_width);
}
location = glGetUniformLocation(program, "osd_active_uv_offset");
if (location != -1) {
if (fvar_data->channel_offsets.size() > 0 && g_active_uv_index >= 0) {
glUniform1i(location, fvar_data->channel_offsets[g_active_uv_index]);
}
else {
glUniform1i(location, 0);
}
}
}
else {
glUniform1i(glGetUniformLocation(program, "osd_fvar_count"), 0);
glUniform1i(glGetUniformLocation(program, "osd_active_uv_offset"), 0);
}
}
return program;
}
if (fill_quads) {
int model;
GLboolean use_texture_2d;
glGetIntegerv(GL_SHADE_MODEL, &model);
glGetBooleanv(GL_TEXTURE_2D, &use_texture_2d);
if (model == GL_FLAT) {
if (use_texture_2d) {
program = g_flat_fill_texture2d_program;
}
else {
program = g_flat_fill_solid_program;
}
}
else {
if (use_texture_2d) {
program = g_smooth_fill_texture2d_program;
}
else {
program = g_smooth_fill_solid_program;
}
}
}
else {
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
program = g_wireframe_program;
}
bindProgram(gl_mesh, program);
return program;
}
void perform_drawElements(GLuint program, int patch_index, int num_elements, int start_element)
{
if (program) {
glUniform1i(glGetUniformLocation(program, "PrimitiveIdBase"), patch_index);
}
glDrawElements(GL_LINES_ADJACENCY,
num_elements,
GL_UNSIGNED_INT,
reinterpret_cast<void *>(start_element * sizeof(unsigned int)));
}
void finishPatchDraw(bool fill_quads)
{
// TODO(sergey): Some of the stuff could be done once after the whole
// mesh is displayed.
/// Restore state.
if (!fill_quads) {
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
}
glBindVertexArray(0);
if (g_use_osd_glsl) {
// TODO(sergey): Store previously used program and roll back to it?
glUseProgram(0);
}
}
void drawPartitionPatchesRange(GLMeshInterface *mesh,
GLuint program,
int start_patch,
int num_patches)
{
int traversed_patches = 0, num_remained_patches = num_patches;
const OpenSubdiv::Osd::PatchArrayVector &patches = mesh->GetPatchTable()->GetPatchArrays();
for (int i = 0; i < patches.size(); ++i) {
const OpenSubdiv::Osd::PatchArray &patch = patches[i];
OpenSubdiv::Far::PatchDescriptor desc = patch.GetDescriptor();
OpenSubdiv::Far::PatchDescriptor::Type patchType = desc.GetType();
if (patchType == OpenSubdiv::Far::PatchDescriptor::QUADS) {
const int num_block_patches = patch.GetNumPatches();
if (start_patch >= traversed_patches &&
start_patch < traversed_patches + num_block_patches) {
const int num_control_verts = desc.GetNumControlVertices();
const int start_draw_patch = start_patch - traversed_patches;
const int num_draw_patches = min(num_remained_patches,
num_block_patches - start_draw_patch);
perform_drawElements(program,
i + start_draw_patch,
num_draw_patches * num_control_verts,
patch.GetIndexBase() + start_draw_patch * num_control_verts);
num_remained_patches -= num_draw_patches;
}
if (num_remained_patches == 0) {
break;
}
traversed_patches += num_block_patches;
}
}
}
static void drawAllPatches(GLMeshInterface *mesh, GLuint program)
{
const OpenSubdiv::Osd::PatchArrayVector &patches = mesh->GetPatchTable()->GetPatchArrays();
for (int i = 0; i < patches.size(); ++i) {
const OpenSubdiv::Osd::PatchArray &patch = patches[i];
OpenSubdiv::Far::PatchDescriptor desc = patch.GetDescriptor();
OpenSubdiv::Far::PatchDescriptor::Type patchType = desc.GetType();
if (patchType == OpenSubdiv::Far::PatchDescriptor::QUADS) {
perform_drawElements(
program, i, patch.GetNumPatches() * desc.GetNumControlVertices(), patch.GetIndexBase());
}
}
}
} // namespace
void GLMeshDisplayPrepare(struct OpenSubdiv_GLMesh * /*gl_mesh*/,
const bool use_osd_glsl,
const int active_uv_index)
{
g_active_uv_index = active_uv_index;
g_use_osd_glsl = (use_osd_glsl != 0);
// Update transformation matrices.
glGetFloatv(GL_PROJECTION_MATRIX, g_transform.projection_matrix);
glGetFloatv(GL_MODELVIEW_MATRIX, g_transform.model_view_matrix);
copy_m3_m4((float(*)[3])g_transform.normal_matrix, (float(*)[4])g_transform.model_view_matrix);
invert_m3((float(*)[3])g_transform.normal_matrix);
transpose_m3((float(*)[3])g_transform.normal_matrix);
// Update OpenGL lights positions, colors etc.
g_lighting_data.num_enabled = 0;
for (int i = 0; i < MAX_LIGHTS; ++i) {
GLboolean enabled;
glGetBooleanv(GL_LIGHT0 + i, &enabled);
if (enabled) {
g_lighting_data.num_enabled++;
}
// TODO(sergey): Stop using glGetLight.
glGetLightfv(GL_LIGHT0 + i, GL_POSITION, g_lighting_data.lights[i].position);
glGetLightfv(GL_LIGHT0 + i, GL_AMBIENT, g_lighting_data.lights[i].ambient);
glGetLightfv(GL_LIGHT0 + i, GL_DIFFUSE, g_lighting_data.lights[i].diffuse);
glGetLightfv(GL_LIGHT0 + i, GL_SPECULAR, g_lighting_data.lights[i].specular);
glGetLightfv(GL_LIGHT0 + i, GL_SPOT_DIRECTION, g_lighting_data.lights[i].spot_direction);
#ifdef SUPPORT_COLOR_MATERIAL
glGetLightfv(
GL_LIGHT0 + i, GL_CONSTANT_ATTENUATION, &g_lighting_data.lights[i].constant_attenuation);
glGetLightfv(
GL_LIGHT0 + i, GL_LINEAR_ATTENUATION, &g_lighting_data.lights[i].linear_attenuation);
glGetLightfv(
GL_LIGHT0 + i, GL_QUADRATIC_ATTENUATION, &g_lighting_data.lights[i].quadratic_attenuation);
glGetLightfv(GL_LIGHT0 + i, GL_SPOT_CUTOFF, &g_lighting_data.lights[i].spot_cutoff);
glGetLightfv(GL_LIGHT0 + i, GL_SPOT_EXPONENT, &g_lighting_data.lights[i].spot_exponent);
g_lighting_data.lights[i].spot_cos_cutoff = cos(g_lighting_data.lights[i].spot_cutoff);
#endif
}
}
void GLMeshDisplayDrawPatches(OpenSubdiv_GLMesh *gl_mesh,
const bool fill_quads,
const int start_patch,
const int num_patches)
{
GLMeshInterface *mesh = gl_mesh->internal->mesh_interface;
// Make sure all global invariants are initialized.
if (!openSubdiv_initGLMeshDrawingResources()) {
return;
}
/// Setup GLSL/OpenGL to draw patches in current context.
GLuint program = prepare_patchDraw(gl_mesh, fill_quads != 0);
if (start_patch != -1) {
drawPartitionPatchesRange(mesh, program, start_patch, num_patches);
}
else {
drawAllPatches(mesh, program);
}
// Finish patch drawing by restoring all changes to the OpenGL context.
finishPatchDraw(fill_quads != 0);
}
} // namespace opensubdiv_capi

View File

@ -1,39 +0,0 @@
// Copyright 2013 Blender Foundation. All rights reserved.
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software Foundation,
// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
//
// Author: Sergey Sharybin
#ifndef OPENSUBDIV_GL_MESH_DRAW_H_
#define OPENSUBDIV_GL_MESH_DRAW_H_
#include <stdint.h> // for bool
struct OpenSubdiv_GLMesh;
namespace opensubdiv_capi {
void GLMeshDisplayPrepare(struct OpenSubdiv_GLMesh *gl_mesh,
const bool use_osd_glsl,
const int active_uv_index);
void GLMeshDisplayDrawPatches(OpenSubdiv_GLMesh *gl_mesh,
const bool fill_quads,
const int start_patch,
const int num_patches);
} // namespace opensubdiv_capi
#endif // OPENSUBDIV_GL_MESH_DRAW_H_

View File

@ -1,171 +0,0 @@
// Copyright 2013 Blender Foundation. All rights reserved.
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software Foundation,
// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
//
// Author: Sergey Sharybin
#include "internal/opensubdiv_gl_mesh_fvar.h"
#include <GL/glew.h>
#include <opensubdiv/far/primvarRefiner.h>
#include "internal/opensubdiv_util.h"
namespace opensubdiv_capi {
////////////////////////////////////////////////////////////////////////////////
// GLMeshFVarData
GLMeshFVarData::GLMeshFVarData() : texture_buffer(0), offset_buffer(0)
{
}
GLMeshFVarData::~GLMeshFVarData()
{
release();
}
void GLMeshFVarData::release()
{
if (texture_buffer) {
glDeleteTextures(1, &texture_buffer);
}
if (offset_buffer) {
glDeleteTextures(1, &offset_buffer);
}
texture_buffer = 0;
offset_buffer = 0;
fvar_width = 0;
channel_offsets.clear();
}
void GLMeshFVarData::create(const OpenSubdiv::Far::TopologyRefiner *topology_refiner,
const OpenSubdiv::Far::PatchTable *patch_table,
int fvar_width,
const float *fvar_src_data)
{
release();
this->fvar_width = fvar_width;
/// Expand fvar data to per-patch array.
const int max_level = topology_refiner->GetMaxLevel();
const int num_channels = patch_table->GetNumFVarChannels();
vector<float> data;
int fvar_data_offset = 0;
channel_offsets.resize(num_channels);
for (int channel = 0; channel < num_channels; ++channel) {
OpenSubdiv::Far::ConstIndexArray indices = patch_table->GetFVarValues(channel);
channel_offsets[channel] = data.size();
data.reserve(data.size() + indices.size() * fvar_width);
for (int fvert = 0; fvert < indices.size(); ++fvert) {
int index = indices[fvert] * fvar_width;
for (int i = 0; i < fvar_width; ++i) {
data.push_back(fvar_src_data[fvar_data_offset + index++]);
}
}
if (topology_refiner->IsUniform()) {
const int num_values_max = topology_refiner->GetLevel(max_level).GetNumFVarValues(channel);
fvar_data_offset += num_values_max * fvar_width;
}
else {
const int num_values_total = topology_refiner->GetNumFVarValuesTotal(channel);
fvar_data_offset += num_values_total * fvar_width;
}
}
GLuint buffer;
glGenBuffers(1, &buffer);
glBindBuffer(GL_ARRAY_BUFFER, buffer);
glBufferData(GL_ARRAY_BUFFER, data.size() * sizeof(float), &data[0], GL_STATIC_DRAW);
glGenTextures(1, &texture_buffer);
glBindTexture(GL_TEXTURE_BUFFER, texture_buffer);
glTexBuffer(GL_TEXTURE_BUFFER, GL_R32F, buffer);
glDeleteBuffers(1, &buffer);
glGenBuffers(1, &buffer);
glBindBuffer(GL_ARRAY_BUFFER, buffer);
glBufferData(
GL_ARRAY_BUFFER, channel_offsets.size() * sizeof(int), &channel_offsets[0], GL_STATIC_DRAW);
glGenTextures(1, &offset_buffer);
glBindTexture(GL_TEXTURE_BUFFER, offset_buffer);
glTexBuffer(GL_TEXTURE_BUFFER, GL_R32I, buffer);
glBindTexture(GL_TEXTURE_BUFFER, 0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
}
////////////////////////////////////////////////////////////////////////////////
// Helper functions.
struct FVarVertex {
float u, v;
void Clear()
{
u = v = 0.0f;
}
void AddWithWeight(FVarVertex const &src, float weight)
{
u += weight * src.u;
v += weight * src.v;
}
};
void interpolateFVarData(const OpenSubdiv::Far::TopologyRefiner &refiner,
const vector<float> &uvs,
vector<float> *fvar_data)
{
const int fvar_width = 2;
const int max_level = refiner.GetMaxLevel();
size_t fvar_data_offset = 0, values_offset = 0;
for (int channel = 0; channel < refiner.GetNumFVarChannels(); ++channel) {
const int num_values = refiner.GetLevel(0).GetNumFVarValues(channel) * 2;
const int num_values_max = refiner.GetLevel(max_level).GetNumFVarValues(channel);
const int num_values_total = refiner.GetNumFVarValuesTotal(channel);
if (num_values_total <= 0) {
continue;
}
OpenSubdiv::Far::PrimvarRefiner primvar_refiner(refiner);
if (refiner.IsUniform()) {
// For uniform we only keep the highest level of refinement.
fvar_data->resize(fvar_data->size() + num_values_max * fvar_width);
vector<FVarVertex> buffer(num_values_total - num_values_max);
FVarVertex *src = &buffer[0];
memcpy(src, &uvs[values_offset], num_values * sizeof(float));
// Defer the last level to treat separately with its alternate
// destination.
for (int level = 1; level < max_level; ++level) {
FVarVertex *dst = src + refiner.GetLevel(level - 1).GetNumFVarValues(channel);
primvar_refiner.InterpolateFaceVarying(level, src, dst, channel);
src = dst;
}
FVarVertex *dst = reinterpret_cast<FVarVertex *>(&(*fvar_data)[fvar_data_offset]);
primvar_refiner.InterpolateFaceVarying(max_level, src, dst, channel);
fvar_data_offset += num_values_max * fvar_width;
}
else {
// For adaptive we keep all levels.
fvar_data->resize(fvar_data->size() + num_values_total * fvar_width);
FVarVertex *src = reinterpret_cast<FVarVertex *>(&(*fvar_data)[fvar_data_offset]);
memcpy(src, &uvs[values_offset], num_values * sizeof(float));
for (int level = 1; level <= max_level; ++level) {
FVarVertex *dst = src + refiner.GetLevel(level - 1).GetNumFVarValues(channel);
primvar_refiner.InterpolateFaceVarying(level, src, dst, channel);
src = dst;
}
fvar_data_offset += num_values_total * fvar_width;
}
values_offset += num_values;
}
}
} // namespace opensubdiv_capi

View File

@ -1,57 +0,0 @@
// Copyright 2013 Blender Foundation. All rights reserved.
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software Foundation,
// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
//
// Author: Sergey Sharybin
#ifndef OPENSUBDIV_GL_MESH_FVAR_H_
#define OPENSUBDIV_GL_MESH_FVAR_H_
// NOTE: This is a [sane(er)] port of previous ground work for getting UVs to
// work. Still needs a lot of work to make it easy, correct and have proper
// data ownership.
#include <opensubdiv/far/patchTable.h>
#include <opensubdiv/far/topologyRefiner.h>
#include "internal/opensubdiv_util.h"
namespace opensubdiv_capi {
// The buffer which holds GPU resources for face-varying elements.
class GLMeshFVarData {
public:
GLMeshFVarData();
~GLMeshFVarData();
void release();
void create(const OpenSubdiv::Far::TopologyRefiner *refiner,
const OpenSubdiv::Far::PatchTable *patch_table,
int fvar_width,
const float *fvar_src_data);
unsigned int texture_buffer;
unsigned int offset_buffer;
vector<int> channel_offsets;
int fvar_width;
};
void interpolateFVarData(const OpenSubdiv::Far::TopologyRefiner &refiner,
const vector<float> &uvs,
vector<float> *fvar_data);
} // namespace opensubdiv_capi
#endif // OPENSUBDIV_GL_MESH_FVAR_H_

View File

@ -1,32 +0,0 @@
// Copyright 2018 Blender Foundation. All rights reserved.
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software Foundation,
// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
//
// Author: Sergey Sharybin
#include "internal/opensubdiv_gl_mesh_internal.h"
#include "internal/opensubdiv_gl_mesh_fvar.h"
OpenSubdiv_GLMeshInternal::OpenSubdiv_GLMeshInternal()
: evaluator_type(OPENSUBDIV_EVALUATOR_CPU), mesh_interface(NULL), fvar_data(NULL)
{
}
OpenSubdiv_GLMeshInternal::~OpenSubdiv_GLMeshInternal()
{
delete mesh_interface;
delete fvar_data;
}

View File

@ -1,43 +0,0 @@
// Copyright 2018 Blender Foundation. All rights reserved.
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software Foundation,
// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
//
// Author: Sergey Sharybin
#ifndef OPENSUBDIV_GL_MESH_INTERNAL_H_
#define OPENSUBDIV_GL_MESH_INTERNAL_H_
#ifdef _MSC_VER
# include <iso646.h>
#endif
#include <opensubdiv/osd/glMesh.h>
#include "opensubdiv_capi_type.h"
namespace opensubdiv_capi {
class GLMeshFVarData;
} // namespace opensubdiv_capi
typedef struct OpenSubdiv_GLMeshInternal {
OpenSubdiv_GLMeshInternal();
~OpenSubdiv_GLMeshInternal();
eOpenSubdivEvaluator evaluator_type;
OpenSubdiv::Osd::GLMeshInterface *mesh_interface;
opensubdiv_capi::GLMeshFVarData *fvar_data;
} OpenSubdiv_GLMeshInternal;
#endif // OPENSUBDIV_GL_MESH_INTERNAL_H_

View File

@ -1,92 +0,0 @@
// Copyright 2013 Blender Foundation. All rights reserved.
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software Foundation,
// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
//
// Author: Sergey Sharybin
#ifndef OPENSUBDIV_CAPI_GL_MESH_CAPI_H_
#define OPENSUBDIV_CAPI_GL_MESH_CAPI_H_
#include <stdint.h> // for bool
#include "opensubdiv_capi_type.h"
#ifdef __cplusplus
extern "C" {
#endif
struct OpenSubdiv_GLMeshInternal;
// Mesh which is displayable in OpenGL context.
typedef struct OpenSubdiv_GLMesh {
//////////////////////////////////////////////////////////////////////////////
// Subdivision/topology part.
// Returns the GL index buffer containing the patch control vertices.
unsigned int (*getPatchIndexBuffer)(struct OpenSubdiv_GLMesh *gl_mesh);
// Bind GL buffer which contains vertices (VBO).
// TODO(sergey): Is this a coarse vertices?
void (*bindVertexBuffer)(struct OpenSubdiv_GLMesh *gl_mesh);
// Set coarse positions from a continuous array of coordinates.
void (*setCoarsePositions)(struct OpenSubdiv_GLMesh *gl_mesh,
const float *positions,
const int start_vertex,
const int num_vertices);
// TODO(sergey): setCoarsePositionsFromBuffer().
// Refine after coarse positions update.
void (*refine)(struct OpenSubdiv_GLMesh *gl_mesh);
// Synchronize after coarse positions update and refine.
void (*synchronize)(struct OpenSubdiv_GLMesh *gl_mesh);
//////////////////////////////////////////////////////////////////////////////
// Drawing part.
// Prepare mesh for display.
void (*prepareDraw)(struct OpenSubdiv_GLMesh *gl_mesh,
const bool use_osd_glsl,
const int active_uv_index);
// Draw given range of patches.
//
// If fill_quads is false, then patches are drawn in wireframe.
void (*drawPatches)(struct OpenSubdiv_GLMesh *gl_mesh,
const bool fill_quads,
const int start_patch,
const int num_patches);
// Internal storage for the use in this module only.
//
// Tease: This contains an actual OpenSubdiv's Mesh object.
struct OpenSubdiv_GLMeshInternal *internal;
} OpenSubdiv_GLMesh;
OpenSubdiv_GLMesh *openSubdiv_createOsdGLMeshFromTopologyRefiner(
struct OpenSubdiv_TopologyRefiner *topology_refiner, eOpenSubdivEvaluator evaluator_type);
void openSubdiv_deleteOsdGLMesh(OpenSubdiv_GLMesh *gl_mesh);
// Global resources needed for GL mesh drawing.
bool openSubdiv_initGLMeshDrawingResources(void);
void openSubdiv_deinitGLMeshDrawingResources(void);
#ifdef __cplusplus
}
#endif
#endif // OPENSUBDIV_CAPI_GL_MESH_CAPI_H_

View File

@ -1,163 +0,0 @@
/*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* The Original Code is Copyright (C) 2014 Blender Foundation.
* All rights reserved.
*/
struct VertexData {
vec4 position;
vec3 normal;
vec2 uv;
};
#define MAX_LIGHTS 8
#define NUM_SOLID_LIGHTS 3
struct LightSource {
vec4 position;
vec4 ambient;
vec4 diffuse;
vec4 specular;
vec4 spotDirection;
#ifdef SUPPORT_COLOR_MATERIAL
float constantAttenuation;
float linearAttenuation;
float quadraticAttenuation;
float spotCutoff;
float spotExponent;
float spotCosCutoff;
float pad, pad2;
#endif
};
layout(std140) uniform Lighting
{
LightSource lightSource[MAX_LIGHTS];
int num_enabled_lights;
};
uniform vec4 diffuse;
uniform vec4 specular;
uniform float shininess;
uniform sampler2D texture_buffer;
in block
{
VertexData v;
}
inpt;
void main()
{
#ifdef WIREFRAME
gl_FragColor = diffuse;
#else
vec3 N = inpt.v.normal;
if (!gl_FrontFacing)
N = -N;
/* Compute diffuse and specular lighting. */
vec3 L_diffuse = vec3(0.0);
vec3 L_specular = vec3(0.0);
# ifdef USE_LIGHTING
# ifndef USE_COLOR_MATERIAL
/* Assume NUM_SOLID_LIGHTS directional lights. */
for (int i = 0; i < NUM_SOLID_LIGHTS; i++) {
vec4 Plight = lightSource[i].position;
# ifdef USE_DIRECTIONAL_LIGHT
vec3 l = (Plight.w == 0.0) ? normalize(Plight.xyz) : normalize(inpt.v.position.xyz);
# else /* USE_DIRECTIONAL_LIGHT */
/* TODO(sergey): We can normalize it outside of the shader. */
vec3 l = normalize(Plight.xyz);
# endif /* USE_DIRECTIONAL_LIGHT */
vec3 h = normalize(l + vec3(0, 0, 1));
float d = max(0.0, dot(N, l));
float s = pow(max(0.0, dot(N, h)), shininess);
L_diffuse += d * lightSource[i].diffuse.rgb;
L_specular += s * lightSource[i].specular.rgb;
}
# else /* USE_COLOR_MATERIAL */
vec3 varying_position = inpt.v.position.xyz;
vec3 V = (gl_ProjectionMatrix[3][3] == 0.0) ? normalize(varying_position) : vec3(0.0, 0.0, -1.0);
for (int i = 0; i < num_enabled_lights; i++) {
/* todo: this is a slow check for disabled lights */
if (lightSource[i].specular.a == 0.0)
continue;
float intensity = 1.0;
vec3 light_direction;
if (lightSource[i].position.w == 0.0) {
/* directional light */
light_direction = lightSource[i].position.xyz;
}
else {
/* point light */
vec3 d = lightSource[i].position.xyz - varying_position;
light_direction = normalize(d);
/* spot light cone */
if (lightSource[i].spotCutoff < 90.0) {
float cosine = max(dot(light_direction, -lightSource[i].spotDirection.xyz), 0.0);
intensity = pow(cosine, lightSource[i].spotExponent);
intensity *= step(lightSource[i].spotCosCutoff, cosine);
}
/* falloff */
float distance = length(d);
intensity /= lightSource[i].constantAttenuation +
lightSource[i].linearAttenuation * distance +
lightSource[i].quadraticAttenuation * distance * distance;
}
/* diffuse light */
vec3 light_diffuse = lightSource[i].diffuse.rgb;
float diffuse_bsdf = max(dot(N, light_direction), 0.0);
L_diffuse += light_diffuse * diffuse_bsdf * intensity;
/* specular light */
vec3 light_specular = lightSource[i].specular.rgb;
vec3 H = normalize(light_direction - V);
float specular_bsdf = pow(max(dot(N, H), 0.0), gl_FrontMaterial.shininess);
L_specular += light_specular * specular_bsdf * intensity;
}
# endif /* USE_COLOR_MATERIAL */
# else /* USE_LIGHTING */
L_diffuse = vec3(1.0);
# endif
/* Compute diffuse color. */
# ifdef USE_TEXTURE_2D
L_diffuse *= texture2D(texture_buffer, inpt.v.uv).rgb;
# else
L_diffuse *= diffuse.rgb;
# endif
/* Sum lighting. */
vec3 L = L_diffuse;
if (shininess != 0) {
L += L_specular * specular.rgb;
}
/* Write out fragment color. */
gl_FragColor = vec4(L, diffuse.a);
#endif
}

View File

@ -1,149 +0,0 @@
/*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* The Original Code is Copyright (C) 2014 Blender Foundation.
* All rights reserved.
*/
struct VertexData {
vec4 position;
vec3 normal;
vec2 uv;
};
layout(lines_adjacency) in;
#ifdef WIREFRAME
layout(line_strip, max_vertices = 8) out;
#else
layout(triangle_strip, max_vertices = 4) out;
#endif
uniform mat4 modelViewMatrix;
uniform mat4 projectionMatrix;
uniform int PrimitiveIdBase;
uniform int osd_fvar_count;
uniform int osd_active_uv_offset;
in block
{
VertexData v;
}
inpt[];
#define INTERP_FACE_VARYING_2(result, fvarOffset, tessCoord) \
{ \
vec2 v[4]; \
int primOffset = (gl_PrimitiveID + PrimitiveIdBase) * 4; \
for (int i = 0; i < 4; ++i) { \
int index = (primOffset + i) * osd_fvar_count + fvarOffset; \
v[i] = vec2(texelFetch(FVarDataBuffer, index).s, texelFetch(FVarDataBuffer, index + 1).s); \
} \
result = mix(mix(v[0], v[1], tessCoord.s), mix(v[3], v[2], tessCoord.s), tessCoord.t); \
}
uniform samplerBuffer FVarDataBuffer;
uniform isamplerBuffer FVarDataOffsetBuffer;
out block
{
VertexData v;
}
outpt;
#ifdef FLAT_SHADING
void emit(int index, vec3 normal)
{
outpt.v.position = inpt[index].v.position;
outpt.v.normal = normal;
/* TODO(sergey): Only uniform subdivisions atm. */
vec2 quadst[4] = vec2[](vec2(0, 0), vec2(1, 0), vec2(1, 1), vec2(0, 1));
vec2 st = quadst[index];
INTERP_FACE_VARYING_2(outpt.v.uv, osd_active_uv_offset, st);
gl_Position = projectionMatrix * inpt[index].v.position;
EmitVertex();
}
# ifdef WIREFRAME
void emit_edge(int v0, int v1, vec3 normal)
{
emit(v0, normal);
emit(v1, normal);
}
# endif
#else
void emit(int index)
{
outpt.v.position = inpt[index].v.position;
outpt.v.normal = inpt[index].v.normal;
/* TODO(sergey): Only uniform subdivisions atm. */
vec2 quadst[4] = vec2[](vec2(0, 0), vec2(1, 0), vec2(1, 1), vec2(0, 1));
vec2 st = quadst[index];
INTERP_FACE_VARYING_2(outpt.v.uv, osd_active_uv_offset, st);
gl_Position = projectionMatrix * inpt[index].v.position;
EmitVertex();
}
# ifdef WIREFRAME
void emit_edge(int v0, int v1)
{
emit(v0);
emit(v1);
}
# endif
#endif
void main()
{
gl_PrimitiveID = gl_PrimitiveIDIn;
#ifdef FLAT_SHADING
vec3 A = (inpt[0].v.position - inpt[1].v.position).xyz;
vec3 B = (inpt[3].v.position - inpt[1].v.position).xyz;
vec3 flat_normal = normalize(cross(B, A));
# ifndef WIREFRAME
emit(0, flat_normal);
emit(1, flat_normal);
emit(3, flat_normal);
emit(2, flat_normal);
# else
emit_edge(0, 1, flat_normal);
emit_edge(1, 2, flat_normal);
emit_edge(2, 3, flat_normal);
emit_edge(3, 0, flat_normal);
# endif
#else
# ifndef WIREFRAME
emit(0);
emit(1);
emit(3);
emit(2);
# else
emit_edge(0, 1);
emit_edge(1, 2);
emit_edge(2, 3);
emit_edge(3, 0);
# endif
#endif
EndPrimitive();
}

View File

@ -1,42 +0,0 @@
/*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* The Original Code is Copyright (C) 2014 Blender Foundation.
* All rights reserved.
*/
struct VertexData {
vec4 position;
vec3 normal;
vec2 uv;
};
in vec3 normal;
in vec4 position;
uniform mat4 modelViewMatrix;
uniform mat3 normalMatrix;
out block
{
VertexData v;
}
outpt;
void main()
{
outpt.v.position = modelViewMatrix * position;
outpt.v.normal = normalize(normalMatrix * normal);
}

View File

@ -1,40 +0,0 @@
// Copyright 2018 Blender Foundation. All rights reserved.
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software Foundation,
// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
//
// Author: Sergey Sharybin
#include "opensubdiv_gl_mesh_capi.h"
#include <cstddef>
struct OpenSubdiv_GLMesh *openSubdiv_createOsdGLMeshFromTopologyRefiner(
OpenSubdiv_TopologyRefiner * /*topology_refiner*/, eOpenSubdivEvaluator /*evaluator_type*/)
{
return NULL;
}
void openSubdiv_deleteOsdGLMesh(OpenSubdiv_GLMesh * /*gl_mesh*/)
{
}
bool openSubdiv_initGLMeshDrawingResources(void)
{
return false;
}
void openSubdiv_deinitGLMeshDrawingResources(void)
{
}