/** **************************************************************************************************** \fn Matrix operator*( const Matrix &i_matrix, const Vector &i_vector ) \brief operator * of Matrix class \param i_matrix the Matrix to be multiplied \param i_vector Vector3 multiplied \return Matrix \retval Result matrix **************************************************************************************************** */ Matrix operator*( const Matrix &i_matrix, const Vector3 &i_vector ) { FUNCTION_START; assert( (i_matrix._u32Row == 1) || (i_matrix._u32Row == 3) ); assert( (i_matrix._u32Column == 1) || (i_matrix._u32Column == 3) ); if( i_matrix._u32Row == 1 ) { Matrix vectorMatrix( 3, 1 ); vectorMatrix(0, 0) = i_vector.X(); vectorMatrix(1, 0) = i_vector.Y(); vectorMatrix(2, 0) = i_vector.Z(); FUNCTION_FINISH; return i_matrix * vectorMatrix; } else { Matrix vectorMatrix( 1, 3 ); vectorMatrix( 0, 0 ) = i_vector.X(); vectorMatrix( 0, 1 ) = i_vector.Y(); vectorMatrix( 0, 2 ) = i_vector.Z(); FUNCTION_FINISH; return i_matrix * vectorMatrix; } FUNCTION_FINISH; }
//-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void DrawableVectors::renderImmediateMode(OpenGLContext* oglContext, const MatrixState& matrixState) { #ifdef CVF_OPENGL_ES CVF_FAIL_MSG("Not supported on OpenGL ES"); #else CVF_ASSERT(oglContext); CVF_ASSERT(m_vertexArray->size() == m_vectorArray->size()); CVF_ASSERT(m_vectorGlyph.notNull()); glEnable(GL_NORMALIZE); glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE); glEnable(GL_COLOR_MATERIAL); if (m_colorArray.isNull()) { glColor3fv(m_singleColor.ptr()); } float vectorMat[16]; size_t numVectors = m_vectorArray->size(); size_t i; for (i = 0; i < numVectors; i++) { // Compute/retrieve "matrix" vectorMatrix(i, vectorMat); glPushMatrix(); glMultMatrixf(vectorMat); if (m_colorArray.notNull()) { glColor3fv(m_colorArray->get(i).ptr()); } // Draw the geometry m_vectorGlyph->renderImmediateMode(oglContext, matrixState); glPopMatrix(); } glDisable(GL_NORMALIZE); CVF_CHECK_OGL(oglContext); #endif // CVF_OPENGL_ES }
//-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void DrawableVectors::render(OpenGLContext* oglContext, ShaderProgram* shaderProgram, const MatrixState&) { CVF_CALLSITE_OPENGL(oglContext); CVF_ASSERT(shaderProgram); CVF_ASSERT(shaderProgram->isProgramUsed(oglContext)); CVF_ASSERT(m_vertexArray->size() == m_vectorArray->size()); CVF_ASSERT(m_colorArray.isNull() || (m_colorArray->size() == m_vectorArray->size())); CVF_ASSERT(m_vectorGlyph.notNull()); CVF_ASSERT(m_vectorGlyph->primitiveSetCount() == 1); // Setup Vertex Arrays/vbos const GLvoid* ptrOrOffset = 0; if (m_renderWithVBO && m_glyphVerticesAndNormalsBO.notNull() && m_glyphVerticesAndNormalsBO->isUploaded()) { // Bind VBO for vertex and normal data m_glyphVerticesAndNormalsBO->bindBuffer(oglContext); glVertexAttribPointer(ShaderProgram::NORMAL, 3, GL_FLOAT, GL_FALSE, sizeof(float)*6, (void*)(sizeof(float)*3)); glVertexAttribPointer(ShaderProgram::VERTEX, 3, GL_FLOAT, GL_FALSE, sizeof(float)*6, 0); glEnableVertexAttribArray(ShaderProgram::NORMAL); glEnableVertexAttribArray(ShaderProgram::VERTEX); m_indicesBO->bindBuffer(oglContext); } else { glBindBuffer(GL_ARRAY_BUFFER, 0); glVertexAttribPointer(ShaderProgram::NORMAL, 3, GL_FLOAT, GL_FALSE, 0, m_vectorGlyph->normalArray()->ptr()->ptr()); glEnableVertexAttribArray(ShaderProgram::NORMAL); glVertexAttribPointer(ShaderProgram::VERTEX, 3, GL_FLOAT, GL_FALSE, 0, m_vectorGlyph->vertexArray()->ptr()->ptr()); glEnableVertexAttribArray(ShaderProgram::VERTEX); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); ptrOrOffset = m_vectorGlyphPrimSet->indices()->ptr(); } // Must use manual uniform setting, as setting the uniform through the Uniform* class requires a lookup for location // every time, and this is always the same GLint vectorMatrixUniformLocation = shaderProgram->uniformLocation(m_vectorMatrixUniformName.toAscii().ptr()); CVF_ASSERT(vectorMatrixUniformLocation != -1); GLint colorUniformLocation = shaderProgram->uniformLocation(m_colorUniformName.toAscii().ptr()); CVF_ASSERT(colorUniformLocation != -1); #ifndef CVF_OPENGL_ES uint minIndex = m_vectorGlyphPrimSet->minIndex(); uint maxIndex = m_vectorGlyphPrimSet->maxIndex(); #endif GLsizei indexCount = static_cast<GLsizei>(m_vectorGlyphPrimSet->indexCount()); // Set the single color to use if (m_colorArray.isNull()) { glUniform3fv(colorUniformLocation, 1, m_singleColor.ptr()); } float vectorMat[16]; size_t numVectors = m_vectorArray->size(); size_t i; for (i = 0; i < numVectors; i++) { // Compute the transformation matrix vectorMatrix(i, vectorMat); // Set this as a uniform to the shader program glUniformMatrix4fv(vectorMatrixUniformLocation, 1, GL_FALSE, vectorMat); if (m_colorArray.notNull()) { glUniform3fv(colorUniformLocation, 1, m_colorArray->get(i).ptr()); } // Draw the arrow #ifdef CVF_OPENGL_ES glDrawElements(GL_TRIANGLES, indexCount, GL_UNSIGNED_SHORT, ptrOrOffset); #else glDrawRangeElements(GL_TRIANGLES, minIndex, maxIndex, indexCount, GL_UNSIGNED_SHORT, ptrOrOffset); #endif } // Cleanup glDisableVertexAttribArray(ShaderProgram::VERTEX); glDisableVertexAttribArray(ShaderProgram::NORMAL); CVF_CHECK_OGL(oglContext); // Things to consider for performance: // 1) Uniform arrays evt. Uniform buffer objects // 2) Texture // 3) Texture array // GL_ARB_draw_instanced(); // glDrawElementsInstanced }
int main() { vectorMatrix myMatrix = vectorMatrix(1, 1); //myMatrix.printMatrix(); //myMatrix.reorderMatrix(); cout << "Matrix Sorting Program: \n"; cout << "Allows you to create a custom sixed matrix and then sort its columns by lowest to highest \n"; cout << "You can run the program multiple times without having to close it \n"; cout << "once done sorting one, simply run the create command again to resize your matrix \n \n"; cout << "Commands: \n"; cout << "\n"; cout << "exit: stops the program from running. \n"; cout << "\n"; cout << "create: allows you to create a custom sized matrix. \n"; cout << " entering one value at a time you choose the number of columns and then rows that the matrix will have \n"; cout << "\n"; cout << "sort: sorts the created matrix. \n"; cout << " sorts the values in the matrix in order from lowest to highest in their respective columns \n"; cout << "\n"; while (isRunning) { string input; getline(cin, input); if (input == "exit") { isRunning = false; } else if (input == "create") { cout << "Using this you may create a matrix of your chosen dimensions \n"; cout << "Please Enter the number of Columns you would like: \n"; cout << "\n"; string firstdimensions; getline(cin, firstdimensions); std::istringstream sin1(firstdimensions); int cols = NULL; sin1 >> cols; //always check if user wants to leave program if (firstdimensions == "exit" || firstdimensions == "Exit") { break; } cout << "\n"; cout << "Please Enter the number of Rows you would like: \n"; cout << "\n"; string secondDimensions; getline(cin, secondDimensions); std::istringstream sin2(secondDimensions); int rows = NULL; sin2 >> rows; //always check if user wants to leave program if (secondDimensions == "exit" || secondDimensions == "Exit") { break; } cout << "\n"; //if the trees were assigned then neither will be null - if any are null then it was not a valid input if (rows != NULL && cols != NULL) { myMatrix = vectorMatrix(cols, rows); cout << "\n The following Matrix was created: \n \n"; myMatrix.printMatrix(); } else { cout << "One or more of the selected values were invalid - please tryn again \n"; cout << "Remember - only input numbers please - no spaces \n"; cout << "\n"; } } else if (input == "help")
void vectorMatrix::reorderMatrix() { cout << " \n Rearranging the Matrix now. \n"; int lowestSoFar = INT_MAX; int currentRow = NULL; int currentCol = NULL; int totalRow = NULL; int totalCol = NULL; //grab the total columns and rows for the matrix totalCol = matrix[0].size(); totalRow = matrix.size(); //creat one that wil be used to store the values during sorting - but make it the opposite dimensions to the original one vectorMatrix transferMatrix = vectorMatrix(totalRow, totalCol); vector< vector<int> >::iterator row; vector<int>::iterator col; //use the iterators once again to iterate through the matrix only this time insert each value into the transfer matrix //this method creates the same matrix but rotated on its side - all rows become columns and columns become rows for (row = matrix.begin(); row != matrix.end(); row++) { currentRow = std::distance(matrix.begin(), row); //use the iterator and distance methods to get the current column and rows that we are in when we need them for (col = row->begin(); col != row->end(); col++) { currentCol = std::distance(row->begin(), col); transferMatrix.matrix[currentCol][currentRow] = matrix[currentRow][currentCol]; } } vector< vector<int> >::iterator rowTransfer; vector<int>::iterator colTransfer; int currentRowTransfer = 0; //again use iterators to go through - but this time we only need to iterate through the rows of the transfer matrix - on top of that // c++ has a built in std::sort which sorts in order from lowest to highest - just like i want - so call this for each row for (rowTransfer = transferMatrix.matrix.begin(); rowTransfer != transferMatrix.matrix.end(); rowTransfer++) { currentRowTransfer = std::distance(transferMatrix.matrix.begin(), rowTransfer); std::sort(transferMatrix.matrix[currentRowTransfer].begin(), transferMatrix.matrix[currentRowTransfer].end()); } vector< vector<int> >::iterator rowFinal; vector<int>::iterator colFinal; //now that the rows in the transfer are all sorted - use iterators once again to rotate them back around to being normal way //could probably have just reused iterators and reset them to be more efficient for (rowFinal = transferMatrix.matrix.begin(); rowFinal != transferMatrix.matrix.end(); rowFinal++) { currentRow = std::distance(transferMatrix.matrix.begin(), rowFinal); for (colFinal = rowFinal->begin(); colFinal != rowFinal->end(); colFinal++) { currentCol = std::distance(rowFinal->begin(), colFinal); //transferMatrix.matrix[currentCol][currentRow] = matrix[currentRow][currentCol]; matrix[currentCol][currentRow] = transferMatrix.matrix[currentRow][currentCol]; } } //cout << "printing transfer matrix \n"; debug uses //transferMatrix.printMatrix(); cout << " \n printing sorted matrix \n"; printMatrix(); }