From 9c6387808590f8ea65f37bba17f3683c62ec0722 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Fri, 22 Jul 2016 16:12:03 +0200 Subject: [PATCH] OpenSubdiv: Initial support of UV maps in material shading mode --- .../gpu_shader_opensubd_display.glsl | 1 + intern/opensubdiv/opensubdiv_gpu_capi.cc | 39 +++++++++++++++++-- source/blender/gpu/intern/gpu_codegen.c | 18 +++++---- source/blender/gpu/intern/gpu_material.c | 3 +- source/blender/gpu/intern/gpu_shader.c | 4 ++ .../gpu/shaders/gpu_shader_geometry.glsl | 1 + 6 files changed, 53 insertions(+), 13 deletions(-) diff --git a/intern/opensubdiv/gpu_shader_opensubd_display.glsl b/intern/opensubdiv/gpu_shader_opensubd_display.glsl index 3a9392e994c..cc9e05a11c8 100644 --- a/intern/opensubdiv/gpu_shader_opensubd_display.glsl +++ b/intern/opensubdiv/gpu_shader_opensubd_display.glsl @@ -99,6 +99,7 @@ in block { } uniform samplerBuffer FVarDataBuffer; +uniform isamplerBuffer FVarDataOffsetBuffer; out block { VertexData v; diff --git a/intern/opensubdiv/opensubdiv_gpu_capi.cc b/intern/opensubdiv/opensubdiv_gpu_capi.cc index 60e742c8337..752dce7744c 100644 --- a/intern/opensubdiv/opensubdiv_gpu_capi.cc +++ b/intern/opensubdiv/opensubdiv_gpu_capi.cc @@ -122,7 +122,11 @@ struct OpenSubdiv_GLMeshFVarData 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(); } @@ -140,7 +144,7 @@ struct OpenSubdiv_GLMeshFVarData const int max_level = refiner->GetMaxLevel(); const int num_channels = patch_table->GetNumFVarChannels(); std::vector data; - size_t fvar_data_offset = 0; + int fvar_data_offset = 0; channel_offsets.resize(num_channels); for (int channel = 0; channel < num_channels; ++channel) { OpenSubdiv::Far::ConstIndexArray indices = @@ -173,13 +177,23 @@ struct OpenSubdiv_GLMeshFVarData glGenTextures(1, &texture_buffer); glBindTexture(GL_TEXTURE_BUFFER, texture_buffer); glTexBuffer(GL_TEXTURE_BUFFER, GL_R32F, buffer); - glBindTexture(GL_TEXTURE_BUFFER, 0); - glBindBuffer(GL_ARRAY_BUFFER, 0); 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; - std::vector channel_offsets; + GLuint offset_buffer; + std::vector channel_offsets; int fvar_width; }; @@ -298,6 +312,10 @@ GLuint linkProgram(const char *version, const char *define) glGetUniformLocation(program, "texture_buffer"), 0); /* GL_TEXTURE0 */ + glProgramUniform1i(program, + glGetUniformLocation(program, "FVarDataOffsetBuffer"), + 30); /* GL_TEXTURE30 */ + glProgramUniform1i(program, glGetUniformLocation(program, "FVarDataBuffer"), 31); /* GL_TEXTURE31 */ @@ -357,6 +375,12 @@ void bindProgram(OpenSubdiv_GLMesh *gl_mesh, int program) 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 && @@ -542,6 +566,13 @@ static GLuint prepare_patchDraw(OpenSubdiv_GLMesh *gl_mesh, 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); diff --git a/source/blender/gpu/intern/gpu_codegen.c b/source/blender/gpu/intern/gpu_codegen.c index 8ec932f4184..aec94f9f2cb 100644 --- a/source/blender/gpu/intern/gpu_codegen.c +++ b/source/blender/gpu/intern/gpu_codegen.c @@ -853,11 +853,14 @@ static char *code_generate_geometry(ListBase *nodes, bool use_opensubdiv) for (input = node->inputs.first; input; input = input->next) { if (input->source == GPU_SOURCE_ATTRIB && input->attribfirst) { if (input->attribtype == CD_MTFACE) { + /* NOTE: For now we are using varying on purpose, + * otherwise we are not able to write to the varying. + */ BLI_dynstr_appendf(ds, "%s %s var%d%s;\n", - GLEW_VERSION_3_0 ? "in" : "varying", + "varying", GPU_DATATYPE_STR[input->type], input->attribid, - GLEW_VERSION_3_0 ? "[]" : ""); + ""); BLI_dynstr_appendf(ds, "uniform int fvar%d_offset;\n", input->attribid); } @@ -872,11 +875,12 @@ static char *code_generate_geometry(ListBase *nodes, bool use_opensubdiv) for (input = node->inputs.first; input; input = input->next) { if (input->source == GPU_SOURCE_ATTRIB && input->attribfirst) { if (input->attribtype == CD_MTFACE) { - BLI_dynstr_appendf(ds, - "\t// INTERP_FACE_VARYING_2(var%d, " - "fvar%d_offset, st);\n", - input->attribid, - input->attribid); + BLI_dynstr_appendf( + ds, + "\tINTERP_FACE_VARYING_2(var%d, " + "int(texelFetch(FVarDataOffsetBuffer, fvar%d_offset).r), st);\n", + input->attribid, + input->attribid); } } } diff --git a/source/blender/gpu/intern/gpu_material.c b/source/blender/gpu/intern/gpu_material.c index 98a2ceb472e..4775d2ed30a 100644 --- a/source/blender/gpu/intern/gpu_material.c +++ b/source/blender/gpu/intern/gpu_material.c @@ -2886,8 +2886,7 @@ void GPU_material_update_fvar_offset(GPUMaterial *gpu_material, "fvar%d_offset", input->attribid); location = GPU_shader_get_uniform(shader, name); - /* Multiply by 2 because we're offseting U and V variables. */ - GPU_shader_uniform_int(shader, location, layer_index * 2); + GPU_shader_uniform_int(shader, location, layer_index); } } diff --git a/source/blender/gpu/intern/gpu_shader.c b/source/blender/gpu/intern/gpu_shader.c index 5a1b38e6be7..df1213b01e2 100644 --- a/source/blender/gpu/intern/gpu_shader.c +++ b/source/blender/gpu/intern/gpu_shader.c @@ -436,6 +436,10 @@ GPUShader *GPU_shader_create_ex(const char *vertexcode, #ifdef WITH_OPENSUBDIV /* TODO(sergey): Find a better place for this. */ if (use_opensubdiv && GLEW_VERSION_4_1) { + glProgramUniform1i(shader->program, + glGetUniformLocation(shader->program, "FVarDataOffsetBuffer"), + 30); /* GL_TEXTURE30 */ + glProgramUniform1i(shader->program, glGetUniformLocation(shader->program, "FVarDataBuffer"), 31); /* GL_TEXTURE31 */ diff --git a/source/blender/gpu/shaders/gpu_shader_geometry.glsl b/source/blender/gpu/shaders/gpu_shader_geometry.glsl index 1663915549c..6f063883e37 100644 --- a/source/blender/gpu/shaders/gpu_shader_geometry.glsl +++ b/source/blender/gpu/shaders/gpu_shader_geometry.glsl @@ -32,6 +32,7 @@ uniform int osd_fvar_count; } uniform samplerBuffer FVarDataBuffer; +uniform isamplerBuffer FVarDataOffsetBuffer; out block { VertexData v;