// // Copyright 2013 Pixar // // Licensed under the Apache License, Version 2.0 (the "Apache License") // with the following modification; you may not use this file except in // compliance with the Apache License and the following modification to it: // Section 6. Trademarks. is deleted and replaced with: // // 6. Trademarks. This License does not grant permission to use the trade // names, trademarks, service marks, or product names of the Licensor // and its affiliates, except as required to comply with Section 4(c) of // the License and to reproduce the content of the NOTICE file. // // You may obtain a copy of the Apache License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the Apache License with the above modification is // distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY // KIND, either express or implied. See the Apache License for the specific // language governing permissions and limitations under the Apache License. // #include "gl_mesh.h" #include "gl_fontutils.h" #include "../common/patchColors.h" #include #include #include //------------------------------------------------------------------------------ // color palettes static float g_solidColor[4] = {1.0f, 1.0f, 1.0f, 1.0f}, g_ambientColor[4] = {0.1f, 0.1f, 0.1f, 1.0f}; static float g_levelColors[10][4] = {{1.0f, 1.0f, 1.0f}, {1.0f, 1.0f, 0.0f}, {1.0f, 0.5f, 0.0f}, {0.8f, 0.0f, 0.0f}, {0.0f, 1.0f, 0.5f}, {0.0f, 1.0f, 1.0f}, {0.0f, 0.5f, 1.0f}, {0.0f, 0.5f, 0.5f}, {0.5f, 0.0f, 1.0f}, {1.0f, 0.5f, 1.0f}}; static float g_parentTypeColors[4][4] = {{0.9f, 0.9f, 0.9f}, {0.4f, 0.8f, 0.4f}, {0.8f, 0.8f, 0.4f}, {0.8f, 0.4f, 0.4f}}; //------------------------------------------------------------------------------ void GLMesh::setSolidColor(float * color) { color[0] = _diffuseColor[0]; color[1] = _diffuseColor[1]; color[2] = _diffuseColor[2]; } void GLMesh::setColorByLevel(int level, float * color) { color[0] = g_levelColors[level][0]; color[1] = g_levelColors[level][1]; color[2] = g_levelColors[level][2]; } void GLMesh::setColorBySharpness(float sharpness, float * color) { // 0.0 2.0 4.0 // green --- yellow --- red color[0] = std::min(1.0f, sharpness * 0.5f); color[1] = std::min(1.0f, 2.0f - sharpness * 0.5f); color[2] = 0; } //------------------------------------------------------------------------------ static GLuint g_faceTexture=0; static GLuint getFaceTexture() { #include "face_texture.h" if (not g_faceTexture) { glGenTextures(1, &g_faceTexture); glBindTexture(GL_TEXTURE_2D, g_faceTexture); glPixelStorei(GL_UNPACK_ALIGNMENT, 1); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, FACE_TEXTURE_WIDTH, FACE_TEXTURE_HEIGHT, 0, GL_RGBA, GL_UNSIGNED_BYTE, face_texture); } return g_faceTexture; } //------------------------------------------------------------------------------ GLMesh::GLMesh() : _TBOfaceColors(0) { for (int i=0; i & vbo = _vbo[COMP_VERT]; vbo.resize(nverts * 6); std::vector & eao = _eao[COMP_VERT]; eao.resize(nverts); for (int vert=0; vert & vbo = _vbo[COMP_VERT]; for (int vert=0, ofs=3; vert & vbo = _vbo[COMP_EDGE]; vbo.resize(nedges * 2 * 6); std::vector & eao = _eao[COMP_EDGE]; eao.resize(nedges*2); for (int edge=0; edge & vbo = _vbo[COMP_FACE]; vbo.resize(nverts * 3); memcpy(&vbo[0], vertexData, nverts*sizeof(float)*3); int nfaceverts = 0; for (int i=0; i & eao = _eao[COMP_FACE]; eao.resize(nfaceverts); _faceColors.resize(nfaces*4); int const * fverts = faceverts; for (int face=0, ofs=0; face & vbo = _vbo[COMP_VERT]; // set colors if (options.vertColorMode==VERTCOLOR_BY_LEVEL) { for (int level=0, ofs=3; level<=maxlevel; ++level) { for (int vert=0; vert0) { OpenSubdiv::Far::TopologyLevel const & refPrevLevel = refiner.GetLevel(maxlevel-1); for (int vert=0; vert & vbo = _vbo[COMP_EDGE]; vbo.resize(nedges * 2 * 6); std::vector & eao = _eao[COMP_EDGE]; eao.resize(nedges*2); for (int edge=0; edge & vbo = _vbo[COMP_FACE]; vbo.resize(nverts * 3); memcpy(&vbo[0], vertData, nverts*sizeof(float)*3); int nfaceverts = refLastLevel.GetNumFaceVertices(); std::vector & eao = _eao[COMP_FACE]; eao.resize(nfaceverts); _faceColors.resize(nfaces*4); for (int face=0, ofs=0; face & vbo, int edge, float const * vertData, int v0, int v1, float const * color) { float * dst0 = &vbo[edge*2*6], * dst1 = dst0+6; memcpy(dst0, vertData + (v0*3), sizeof(float)*3); memcpy(dst1, vertData + (v1*3), sizeof(float)*3); memcpy(dst0+3, color, sizeof(float)*3); memcpy(dst1+3, color, sizeof(float)*3); } //------------------------------------------------------------------------------ void GLMesh::InitializeFVar(Options options, TopologyRefiner const & refiner, PatchTable const * patchTable, int channel, int tessFactor, float const * fvarData) { int nverts = refiner.GetNumFVarValuesTotal(channel); { // vertex color component ---------------------------- initializeVertexComponentBuffer(fvarData, nverts); std::vector & vbo = _vbo[COMP_VERT]; if (options.vertColorMode==VERTCOLOR_BY_LEVEL) { for (int level=0, ofs=3; level<=refiner.GetMaxLevel(); ++level) { for (int vert=0; vert0) { // edge color component ------------------------------ int npatches = patchTable->GetNumPatchesTotal(), nvertsperpatch = (tessFactor) * (tessFactor), nedgesperpatch = (tessFactor-1) * (tessFactor*2+tessFactor-1), //nverts = npatches * nvertsperpatch, nedges = npatches * nedgesperpatch; std::vector & vbo = _vbo[COMP_EDGE]; vbo.resize(nedges * 2 * 6); std::vector & eao = _eao[COMP_EDGE]; eao.reserve(nedges*2); // default to solid color float const * color=0; // wireframe indices int * basisedges = (int *)alloca(2*nedgesperpatch*sizeof(int)), * ptr = basisedges; for (int i=0; i<(tessFactor-1); ++i) { // tess pattern : for (int j=0; j<(tessFactor-1); ++j) { // *ptr++ = i*tessFactor + j; // o---o---o-- *ptr++ = i*tessFactor + j+1; // |\ |\ | // | \ | \ | *ptr++ = i * tessFactor + j; // | \| \| *ptr++ = (i+1) * tessFactor + j; // o---o---o-- // |\ |\ | *ptr++ = i * tessFactor + j; // | \ | \ | *ptr++ = (i+1) * tessFactor + j+1; // | \| \| } // o---o---o-- *ptr++ = (i+1) * tessFactor - 1; // | | | *ptr++ = (i+2) * tessFactor - 1; *ptr++ = tessFactor * (tessFactor-1) + i; *ptr++ = tessFactor * (tessFactor-1) + i+1; } OpenSubdiv::Far::PatchTable::PatchHandle handle; for (int patch=0, offset=0; patchGetFVarPatchType(channel, handle); if (OpenSubdiv::Far::PatchDescriptor::IsAdaptive(type)) { color = getAdaptivePatchColor( OpenSubdiv::Far::PatchDescriptor(type)); } else { static float quadColor[3] = { 1.0f, 1.0f, 0.0f }; color = quadColor; } } assert(color); for (int edge=0; edge & vbo = _vbo[COMP_VERT]; if (options.vertColorMode==VERTCOLOR_BY_LEVEL) { for (int level=0, ofs=3; level<=refiner.GetMaxLevel(); ++level) { for (int vert=0; vert & vbo = _vbo[COMP_EDGE]; vbo.resize(nedges * 2 * 6); std::vector & eao = _eao[COMP_EDGE]; eao.resize(nedges*2); // default to solid color float solidColor[3]; setSolidColor(solidColor); float const * color=solidColor; for (int array=0, edge=0; array<(int)patchTable.GetNumPatchArrays(); ++array) { OpenSubdiv::Far::PatchDescriptor desc = patchTable.GetPatchArrayDescriptor(array); if (options.edgeColorMode==EDGECOLOR_BY_PATCHTYPE) { color = getAdaptivePatchColor(desc); } int ncvs = getRingSize(desc); for (int patch=0; patch & vbo = _vbo[COMP_FACE]; vbo.resize(nverts*3); memcpy(&vbo[0], vertexData, nverts*sizeof(float)*3); std::vector & eao = _eao[COMP_FACE]; eao.resize(nfaces*4); _faceColors.resize(nfaces*4, 1.0f); // default to solid color for (int array=0, face=0; array<(int)patchTable.GetNumPatchArrays(); ++array) { OpenSubdiv::Far::PatchDescriptor desc = patchTable.GetPatchArrayDescriptor(array); //int ncvs = getRingSize(desc); for (int patch=0; patch static GLuint createTextureBuffer(T const &data, GLint format, int offset=0) { GLuint buffer = 0, texture = 0; glGenTextures(1, &texture); glGenBuffers(1, &buffer); glBindBuffer(GL_ARRAY_BUFFER, buffer); glBufferData(GL_ARRAY_BUFFER, (data.size()-offset)*sizeof(typename T::value_type), &data[offset], GL_STATIC_DRAW); glBindBuffer(GL_ARRAY_BUFFER, 0); glBindTexture(GL_TEXTURE_BUFFER, texture); glTexBuffer(GL_TEXTURE_BUFFER, format, buffer); glBindTexture(GL_TEXTURE_BUFFER, 0); glDeleteBuffers(1, &buffer); GLUtils::CheckGLErrors("createTextureBuffer"); return texture; } //------------------------------------------------------------------------------ void GLMesh::InitializeDeviceBuffers() { // copy buffers to device for (int i=0; i