diff --git a/include/openspace/rendering/renderablewavefrontobject.h b/include/openspace/rendering/renderablewavefrontobject.h index 8b2d0d66bd..6da1dba82d 100644 --- a/include/openspace/rendering/renderablewavefrontobject.h +++ b/include/openspace/rendering/renderablewavefrontobject.h @@ -52,15 +52,35 @@ public: void render(const RenderData& data) override; void update(const UpdateData& data) override; + typedef struct + { + GLfloat location[3]; + GLfloat tex[2]; + GLfloat normal[3]; + /* GLfloat color[4]; + GLfloat attribute[3]; + GLfloat float_attribute;*/ + //GLubyte padding[4]; // Pads the struct out to 64 bytes for performance increase + } Vertex; + protected: void loadTexture(); + void loadObj(const char *filename); private: properties::StringProperty _colorTexturePath; - ghoul::opengl::ProgramObject* _programObject; // remember to add shaders! ghoul::opengl::Texture* _texture; - planetgeometry::PlanetGeometry* _geometry; // < -- change + + GLuint _vaoID = 6; + GLuint _vBufferID = 7; + GLuint _iBufferID = 8; + + GLenum _mode; + unsigned int _isize; + unsigned int _vsize; + Vertex *_varray; + int *_iarray; glm::dmat3 _stateMatrix; // might need this diff --git a/include/openspace/util/constants.h b/include/openspace/util/constants.h index decbce6ceb..179d2dec7f 100644 --- a/include/openspace/util/constants.h +++ b/include/openspace/util/constants.h @@ -67,8 +67,7 @@ namespace planetgeometry { } // namespace planetgeometry namespace renderablewavefrontobject { - const std::string keyGeometry = "Geometry"; - const std::string keyFrame = "Frame"; + const std::string keyObjFile = "ObjFile"; } // namespace renderableplanet namespace renderablestars { diff --git a/src/rendering/renderablewavefrontobject.cpp b/src/rendering/renderablewavefrontobject.cpp index e0ebb7d18c..a20949055f 100644 --- a/src/rendering/renderablewavefrontobject.cpp +++ b/src/rendering/renderablewavefrontobject.cpp @@ -22,10 +22,14 @@ * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * ****************************************************************************************/ +// temporary includes (will fix as soon as I figure out how class hierarchy should work, +// ie after I see model on screen) +#include +#include + // open space includes #include #include -#include #include #include @@ -48,39 +52,205 @@ RenderableWavefrontObject::RenderableWavefrontObject(const ghoul::Dictionary& di , _colorTexturePath("colorTexture", "Color Texture") , _programObject(nullptr) , _texture(nullptr) - , _geometry(nullptr) { std::string name; bool success = dictionary.getValue(constants::scenegraphnode::keyName, name); assert(success); - std::string path; - success = dictionary.getValue(constants::scenegraph::keyPathModule, path); - assert(success); + std::string path; + dictionary.getValue(constants::renderablestars::keyPathModule, path); - ghoul::Dictionary geometryDictionary; - success = dictionary.getValueSafe( - constants::renderableplanet::keyGeometry, geometryDictionary); - if (success) { - geometryDictionary.setValue(constants::scenegraphnode::keyName, name); - geometryDictionary.setValue(constants::scenegraph::keyPathModule, path); - _geometry - = planetgeometry::PlanetGeometry::createFromDictionary(geometryDictionary); + std::string texturePath = ""; + if (dictionary.hasKey("Textures.Color")) { + dictionary.getValue("Textures.Color", texturePath); + _colorTexturePath = path + "/" + texturePath; } - dictionary.getValue(constants::renderableplanet::keyFrame, _target); - - // TODO: textures need to be replaced by a good system similar to the geometry as soon - // as the requirements are fixed (ab) - std::string texturePath = ""; - success = dictionary.getValueSafe("Textures.Color", texturePath); - if (success) - _colorTexturePath = path + "/" + texturePath; - - addPropertySubOwner(_geometry); - addProperty(_colorTexturePath); _colorTexturePath.onChange(std::bind(&RenderableWavefrontObject::loadTexture, this)); + + _mode = GL_TRIANGLES; + + std::string filename; + std::ifstream ifile(filename.c_str()); + if (ifile){ + LDEBUG("Found file..\n"); + ifile.close(); + loadObj(filename.c_str()); + }else { + LERROR("Did not find file..\n"); + } + +} + +void RenderableWavefrontObject::loadObj(const char *filename){ + // temporary + int vertexSize = 0; + int vertexNormalSize = 0; + int vertexTextureSize = 0; + int indicesSize = 0; + + float f1, f2, f3; + int i1, i2, i3, i4, i5, i6, i7, i8, i9; + char line[150]; + float maxtex = 0.0; + + FILE *fi; + // START LINE COUNT + fi = fopen(filename, "r"); + if (fi == NULL) { + LERROR("Null Object\n"); + } + while (fgets(line, 150, fi) != NULL) + { + if (sscanf(line, "v %f%f%f", &f1, &f2, &f3)) { + vertexSize += 3; + } + if (sscanf(line, "vn %f%f%f", &f1, &f2, &f3)) { + vertexNormalSize += 3; + } + if (sscanf(line, "vt %f%f%f", &f1, &f2, &f3)) { + vertexTextureSize += 3; + } + if (vertexTextureSize > 0) { + if (sscanf(line, "f %i/%i/%i %i/%i/%i %i/%i/%i", &i1, &i2, &i3, &i4, &i5, &i6, &i7, &i8, &i9)) { + indicesSize += 3; + } + } + else { + if (sscanf(line, "f %i//%i %i//%i %i//%i", &i1, &i2, &i3, &i4, &i5, &i6)) { + indicesSize += 3; + } + } + } + /* END LINE COUNT */ + + // allocate memory for all arrays + _isize = indicesSize; + _vsize = indicesSize; + + // float arrays + float *tempVertexArray = (float*)malloc(vertexSize*sizeof(float)); + float *tempVertexNormalArray = (float*)malloc(vertexNormalSize*sizeof(float)); + float *tempVertexTextureArray = (float*)malloc(vertexTextureSize*sizeof(float)); + _varray = (Vertex*)malloc(_vsize*sizeof(Vertex)); + + // int arrays + _iarray = (int*)malloc(_isize*sizeof(int)); + int *tempNormalIndicesArray = (int*)malloc(_isize*sizeof(int)); + int *tempTextureIndicesArray = (int*)malloc(_isize*sizeof(int)); + + // keeping track of the array indexes + unsigned int i = 0; + unsigned int n = 0; + unsigned int m = 0; + unsigned int w = 0; + + // Go back to beginning of file + fseek(fi, 0, SEEK_SET); + while (fgets(line, 150, fi) != NULL){ + if (sscanf(line, "v %f%f%f", &f1, &f2, &f3)){ + (tempVertexArray)[i] = f1; + i++; + (tempVertexArray)[i] = f2; + i++; + (tempVertexArray)[i] = f3; + i++; + } + if (sscanf(line, "vn %f%f%f", &f1, &f2, &f3)){ + (tempVertexNormalArray)[n] = f1; + n++; + (tempVertexNormalArray)[n] = f2; + n++; + (tempVertexNormalArray)[n] = f3; + n++; + } + if (sscanf(line, "vt %f%f%f", &f1, &f2, &f3)){ + (tempVertexTextureArray)[w] = f1; + maxtex = ((tempVertexTextureArray)[w] > maxtex) ? (tempVertexTextureArray)[w] : maxtex; + w++; + (tempVertexTextureArray)[w] = f2; + maxtex = ((tempVertexTextureArray)[w] > maxtex) ? (tempVertexTextureArray)[w] : maxtex; + w++; + (tempVertexTextureArray)[w] = f3; + maxtex = ((tempVertexTextureArray)[w] > maxtex) ? (tempVertexTextureArray)[w] : maxtex; + w++; + } + if (vertexTextureSize > 0){ + if (sscanf(line, "f %i/%i/%i %i/%i/%i %i/%i/%i", &i1, &i2, &i3, &i4, &i5, &i6, &i7, &i8, &i9)){ + (_iarray)[m] = i1 - 1; + (tempTextureIndicesArray)[m] = i2 - 1; + (tempNormalIndicesArray)[m] = i3 - 1; + m++; + (_iarray)[m] = i4 - 1; + (tempTextureIndicesArray)[m] = i5 - 1; + (tempNormalIndicesArray)[m] = i6 - 1; + m++; + (_iarray)[m] = i7 - 1; + (tempTextureIndicesArray)[m] = i8 - 1; + (tempNormalIndicesArray)[m] = i9 - 1; + m++; + } + }else{ + if (sscanf(line, "f %i//%i %i//%i %i//%i", &i1, &i2, &i3, &i4, &i5, &i6)){ + (_iarray)[m] = i1 - 1; + (tempNormalIndicesArray)[m] = i2 - 1; + m++; + (_iarray)[m] = i3 - 1; + (tempNormalIndicesArray)[m] = i4 - 1; + m++; + (_iarray)[m] = i5 - 1; + (tempNormalIndicesArray)[m] = i6 - 1; + m++; + } + } + } + fclose(fi); + // end of file read + // creating the vertex array + i = 0; n = 0; m = 0; + int normalIndex = 0; + int textureIndex = 0; + int vertexIndex = 0; + while (m<_vsize){ + normalIndex = tempNormalIndicesArray[m] * 3; + textureIndex = tempTextureIndicesArray[m] * 3; + vertexIndex = _iarray[m] * 3; + _iarray[m] = m; + + int q = 0; + while (q < 3){ + _varray[m].location[q] = tempVertexArray[vertexIndex + q]; + _varray[m].normal[q] = tempVertexNormalArray[normalIndex + q]; + q++; + } + // needs to be added at some point... + /* + _varray[m].color[0] = 1; + _varray[m].color[1] = 1; + _varray[m].color[2] = 1; + _varray[m].color[3] = 1.0; + + _varray[m].attribute[0] = 0; + _varray[m].attribute[1] = 0; + _varray[m].attribute[2] = 0; + _varray[m].float_attribute = 0; + */ + if (vertexTextureSize > 0){ + _varray[m].tex[0] = tempVertexTextureArray[textureIndex]; + _varray[m].tex[1] = tempVertexTextureArray[textureIndex + 1]; + }else{ + _varray[m].tex[0] = 1.0; + _varray[m].tex[1] = 1.0; + } + m++; + } + // free up memory + free(tempVertexArray); + free(tempVertexNormalArray); + free(tempNormalIndicesArray); + free(tempVertexTextureArray); + free(tempTextureIndicesArray); } RenderableWavefrontObject::~RenderableWavefrontObject(){ @@ -92,21 +262,61 @@ bool RenderableWavefrontObject::initialize() bool completeSuccess = true; if (_programObject == nullptr) completeSuccess - &= OsEng.ref().configurationManager().getValue("pscShader", _programObject); + &= OsEng.ref().configurationManager().getValue("pscShader", _programObject); // it will have own shader later on. loadTexture(); completeSuccess &= (_texture != nullptr); + //completeSuccess &= _geometry->initialize(this); +// --------------------------------------------------------------------------------- powerscaled sphere ----- + // Initialize and upload to graphics card + GLuint errorID; + if (_vaoID == 0) glGenVertexArrays(1, &_vaoID); + if (_vBufferID == 0) { + glGenBuffers(1, &_vBufferID); + if (_vBufferID == 0) { + LERROR("Could not create vertex buffer"); + return false; + } + } - //completeSuccess &= _geometry->initialize(this); + if (_iBufferID == 0) { + glGenBuffers(1, &_iBufferID); + if (_iBufferID == 0) { + LERROR("Could not create index buffer"); + return false; + } + } + // First VAO setup + glBindVertexArray(_vaoID); + glBindBuffer(GL_ARRAY_BUFFER, _vBufferID); + glBufferData(GL_ARRAY_BUFFER, _vsize * sizeof(Vertex), _varray, GL_STATIC_DRAW); + + glEnableVertexAttribArray(0); + glEnableVertexAttribArray(1); + glEnableVertexAttribArray(2); + glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, sizeof(Vertex), + reinterpret_cast(offsetof(Vertex, location))); + glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), + reinterpret_cast(offsetof(Vertex, tex))); + glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), + reinterpret_cast(offsetof(Vertex, normal))); + + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _iBufferID); + glBufferData(GL_ELEMENT_ARRAY_BUFFER, _isize * sizeof(int), _iarray, GL_STATIC_DRAW); + + glBindVertexArray(0); + + errorID = glGetError(); + if (errorID != GL_NO_ERROR) { + LERROR("OpenGL error: " << glewGetErrorString(errorID)); + return false; + } return completeSuccess; } bool RenderableWavefrontObject::deinitialize() { - _geometry->deinitialize(); - delete _geometry; - _geometry = nullptr; delete _texture; _texture = nullptr; return true; @@ -142,7 +352,6 @@ void RenderableWavefrontObject::render(const RenderData& data) } } transform = transform* rot; - // setup the data to the shader _programObject->setUniform("ViewProjection", data.camera.viewProjectionMatrix()); @@ -156,7 +365,7 @@ void RenderableWavefrontObject::render(const RenderData& data) _programObject->setUniform("texture1", unit); // render - _geometry->render(); + //_geometry->render(); // disable shader _programObject->deactivate(); @@ -166,7 +375,7 @@ void RenderableWavefrontObject::render(const RenderData& data) void RenderableWavefrontObject::update(const UpdateData& data) { // set spice-orientation in accordance to timestamp - openspace::SpiceManager::ref().getPositionTransformMatrixGLM("GALACTIC", "IAU_EARTH", data.time, _stateMatrix); + //openspace::SpiceManager::ref().getPositionTransformMatrixGLM("GALACTIC", "IAU_EARTH", data.time, _stateMatrix); }