diff options
Diffstat (limited to 'intern/opensubdiv/opensubdiv_gpu_capi.cc')
-rw-r--r-- | intern/opensubdiv/opensubdiv_gpu_capi.cc | 787 |
1 files changed, 0 insertions, 787 deletions
diff --git a/intern/opensubdiv/opensubdiv_gpu_capi.cc b/intern/opensubdiv/opensubdiv_gpu_capi.cc deleted file mode 100644 index 7d8085c1ff5..00000000000 --- a/intern/opensubdiv/opensubdiv_gpu_capi.cc +++ /dev/null @@ -1,787 +0,0 @@ -/* - * ***** BEGIN GPL LICENSE BLOCK ***** - * - * 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) 2013 Blender Foundation. - * All rights reserved. - * - * Contributor(s): Sergey Sharybin - * - * ***** END GPL LICENSE BLOCK ***** - */ - -#include "opensubdiv_capi.h" - -#ifdef _MSC_VER -# include "iso646.h" -#endif - -#include <cstdio> -#include <cmath> -#include <GL/glew.h> - -#include <opensubdiv/osd/glMesh.h> - -#ifdef OPENSUBDIV_HAS_CUDA -# include <opensubdiv/osd/cudaGLVertexBuffer.h> -#endif /* OPENSUBDIV_HAS_CUDA */ - -#include <opensubdiv/osd/cpuGLVertexBuffer.h> -#include <opensubdiv/osd/cpuEvaluator.h> - -#include "MEM_guardedalloc.h" - -#include "opensubdiv_capi.h" -#include "opensubdiv_topology_refiner.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): This is 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; - -struct OpenSubdiv_GLMeshFVarData -{ - OpenSubdiv_GLMeshFVarData() : - texture_buffer(0), offset_buffer(0) { - } - - ~OpenSubdiv_GLMeshFVarData() - { - Release(); - } - - void 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 Create(const OpenSubdiv::Far::TopologyRefiner *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 = refiner->GetMaxLevel(); - const int num_channels = patch_table->GetNumFVarChannels(); - std::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 < (int)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 (refiner->IsUniform()) { - const int num_values_max = refiner->GetLevel(max_level).GetNumFVarValues(channel); - fvar_data_offset += num_values_max * fvar_width; - } else { - const int num_values_total = 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); - } - GLuint texture_buffer; - GLuint offset_buffer; - std::vector<int> channel_offsets; - int fvar_width; -}; - -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); /* GL_TEXTURE0 */ - - glProgramUniform1i(program, - glGetUniformLocation(program, "FVarDataOffsetBuffer"), - 30); /* GL_TEXTURE30 */ - - glProgramUniform1i(program, - glGetUniformLocation(program, "FVarDataBuffer"), - 31); /* GL_TEXTURE31 */ - } - else { - glUseProgram(program); - glUniform1i(glGetUniformLocation(program, "texture_buffer"), 0); /* GL_TEXTURE0 */ - glUniform1i(glGetUniformLocation(program, "FVarDataOffsetBuffer"), 30); /* GL_TEXTURE30 */ - glUniform1i(glGetUniformLocation(program, "FVarDataBuffer"), 31); /* GL_TEXTURE31 */ - 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: 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 */ - if (gl_mesh->fvar_data != NULL) { - if (gl_mesh->fvar_data->texture_buffer) { - glActiveTexture(GL_TEXTURE31); - glBindTexture(GL_TEXTURE_BUFFER, gl_mesh->fvar_data->texture_buffer); - glActiveTexture(GL_TEXTURE0); - } - - if (gl_mesh->fvar_data->offset_buffer) { - glActiveTexture(GL_TEXTURE30); - glBindTexture(GL_TEXTURE_BUFFER, gl_mesh->fvar_data->offset_buffer); - glActiveTexture(GL_TEXTURE0); - } - - glUniform1i(glGetUniformLocation(program, "osd_fvar_count"), - gl_mesh->fvar_data->fvar_width); - if (gl_mesh->fvar_data->channel_offsets.size() > 0 && - g_active_uv_index >= 0) - { - glUniform1i(glGetUniformLocation(program, "osd_active_uv_offset"), - gl_mesh->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_osdGLDisplayInit(void) -{ - static bool need_init = true; - static bool init_success = false; - - if (need_init) { - /* TODO: 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_osdGLDisplayDeinit(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 -} - -void openSubdiv_osdGLMeshDisplayPrepare(int use_osd_glsl, - 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: 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 - } -} - -static 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 */ - if (gl_mesh->fvar_data != NULL) { - if (gl_mesh->fvar_data->texture_buffer) { - glActiveTexture(GL_TEXTURE31); - glBindTexture(GL_TEXTURE_BUFFER, - gl_mesh->fvar_data->texture_buffer); - glActiveTexture(GL_TEXTURE0); - } - - if (gl_mesh->fvar_data->offset_buffer) { - glActiveTexture(GL_TEXTURE30); - glBindTexture(GL_TEXTURE_BUFFER, - gl_mesh->fvar_data->offset_buffer); - glActiveTexture(GL_TEXTURE0); - } - - GLint location = glGetUniformLocation(program, "osd_fvar_count"); - if (location != -1) { - glUniform1i(location, gl_mesh->fvar_data->fvar_width); - } - - location = glGetUniformLocation(program, "osd_active_uv_offset"); - if (location != -1) { - if (gl_mesh->fvar_data->channel_offsets.size() > 0 && - g_active_uv_index >= 0) - { - glUniform1i(location, - gl_mesh->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; -} - -static 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, - (void *)(start_element * sizeof(unsigned int))); -} - -static void finish_patchDraw(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); - } -} - -static void draw_partition_patches_range(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 < (int)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 = std::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 draw_all_patches(GLMeshInterface *mesh, - GLuint program) -{ - const OpenSubdiv::Osd::PatchArrayVector& patches = - mesh->GetPatchTable()->GetPatchArrays(); - for (int i = 0; i < (int)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()); - } - } -} - -void openSubdiv_osdGLMeshDisplay(OpenSubdiv_GLMesh *gl_mesh, - int fill_quads, - int start_patch, - int num_patches) -{ - GLMeshInterface *mesh = - (GLMeshInterface *)(gl_mesh->descriptor); - - /* Make sure all global invariants are initialized. */ - if (!openSubdiv_osdGLDisplayInit()) { - return; - } - - /* Setup GLSL/OpenGL to draw patches in current context. */ - GLuint program = prepare_patchDraw(gl_mesh, fill_quads != 0); - - if (start_patch != -1) { - draw_partition_patches_range(mesh, - program, - start_patch, - num_patches); - } - else { - draw_all_patches(mesh, program); - } - - /* Finish patch drawing by restoring all changes to the OpenGL context. */ - finish_patchDraw(fill_quads != 0); -} - -void openSubdiv_osdGLAllocFVar(OpenSubdiv_TopologyRefinerDescr *topology_refiner, - OpenSubdiv_GLMesh *gl_mesh, - const float *fvar_data) -{ - GLMeshInterface *mesh = - (GLMeshInterface *)(gl_mesh->descriptor); - gl_mesh->fvar_data = OBJECT_GUARDED_NEW(OpenSubdiv_GLMeshFVarData); - gl_mesh->fvar_data->Create(topology_refiner->osd_refiner, - mesh->GetFarPatchTable(), - 2, - fvar_data); -} - -void openSubdiv_osdGLDestroyFVar(OpenSubdiv_GLMesh *gl_mesh) -{ - if (gl_mesh->fvar_data != NULL) { - OBJECT_GUARDED_DELETE(gl_mesh->fvar_data, OpenSubdiv_GLMeshFVarData); - } -} |