OpenSubdiv: Initial support of UV maps in material shading mode

This commit is contained in:
Sergey Sharybin 2016-07-22 16:12:03 +02:00
parent b2f91d8acf
commit 9c63878085
6 changed files with 53 additions and 13 deletions

View File

@ -99,6 +99,7 @@ in block {
}
uniform samplerBuffer FVarDataBuffer;
uniform isamplerBuffer FVarDataOffsetBuffer;
out block {
VertexData v;

View File

@ -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<float> 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<size_t> channel_offsets;
GLuint offset_buffer;
std::vector<int> 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);

View File

@ -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);
}
}
}

View File

@ -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);
}
}

View File

@ -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 */

View File

@ -32,6 +32,7 @@ uniform int osd_fvar_count;
}
uniform samplerBuffer FVarDataBuffer;
uniform isamplerBuffer FVarDataOffsetBuffer;
out block {
VertexData v;