Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'intern/opensubdiv/opensubdiv_gpu_capi.cc')
-rw-r--r--intern/opensubdiv/opensubdiv_gpu_capi.cc788
1 files changed, 0 insertions, 788 deletions
diff --git a/intern/opensubdiv/opensubdiv_gpu_capi.cc b/intern/opensubdiv/opensubdiv_gpu_capi.cc
deleted file mode 100644
index d28b48ddd18..00000000000
--- a/intern/opensubdiv/opensubdiv_gpu_capi.cc
+++ /dev/null
@@ -1,788 +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_gl_mesh.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);
- }
-}