geometry* createSphere(int divisions) { geometry* geom = new geometry(); glm::vec3 v[4] = { glm::vec3(0.0f, 0.0f, 1.0f), glm::vec3(0.0f, 0.942806, -0.333333), glm::vec3(-0.816497, -0.471405, -0.333333), glm::vec3(0.816497, -0.471405, -0.333333) }; glm::vec2 t[4] = { glm::vec2(v[0].x, v[0].y), glm::vec2(v[1].x, v[1].y), glm::vec2(v[2].x, v[2].y), glm::vec2(v[3].x, v[3].y) }; divideTriangle(geom, v[0], v[1], v[2], divisions); divideTriangle(geom, v[3], v[2], v[1], divisions); divideTriangle(geom, v[0], v[3], v[1], divisions); divideTriangle(geom, v[0], v[2], v[3], divisions); createVertexBuffer(geom); createNormalBuffer(geom); createTexBuffer(geom); glBindVertexArray(0); return geom; }
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // HW3a::divideTriangle: // // Recursive subdivision of triangle (a,b,c). Recurse count times. // void HW3a::divideTriangle(vec2 a, vec2 b, vec2 c, int count) { if (count>0) { float midab1 = (a.x() + b.x()) / 2.0; float midab2 = (a.y() + b.y()) / 2.0; float midac1 = (a.x() + c.x()) / 2.0; float midac2 = (a.y() + c.y()) / 2.0; float midbc1 = (b.x() + c.x()) / 2.0; float midbc2 = (b.y() + c.y()) / 2.0; vec2 tema; tema.setX(midab1); tema.setY(midab2); vec2 temb; temb.setX(midac1); temb.setY(midac2); vec2 temc; temc.setX(midbc1); temc.setY(midbc2); divideTriangle(a, tema, temb, count - 1); divideTriangle(c, temb, temc, count - 1); divideTriangle(b, temc, tema, count - 1); divideTriangle(tema, temb, temc, count-1); } else triangle(a, b, c); }
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // HW1b::setSubdivide: // // Slot function to set subdivisions. // void HW1b::setSubdivide(int divisions) { // update slider and spinbox m_subdivideSlider-> blockSignals(true); m_subdivideSlider-> setValue(divisions); m_subdivideSlider-> blockSignals(false); m_subdivideSpinBox-> blockSignals(true); m_subdivideSpinBox-> setValue(divisions); m_subdivideSpinBox-> blockSignals(false); // populate m_points m_points.clear(); divideTriangle(m_init_points[0], m_init_points[1], m_init_points[2], m_subdivideSlider->value()); // populate m_colors m_colors.clear(); for (int i = 0; i < m_points.size() / 3; i++) { // Create a random color float rand_color_val_R = (std::rand() % 255 + 1)/255.0; float rand_color_val_G = (std::rand() % 255 + 1)/255.0; float rand_color_val_B = (std::rand() % 255 + 1)/255.0; m_colors.push_back(QVector3D(rand_color_val_R, rand_color_val_G, rand_color_val_B)); } // redraw updateGL(); }
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // HW1b::divideTriangle: // // Divide triangle recursively. // void HW1b::divideTriangle(QVector2D a, QVector2D b, QVector2D c, int count) { if (count > 0) { QVector2D ab = QVector2D( (a.x() + b.x() ) /2, (a.y() + b.y() ) /2); QVector2D ac = QVector2D( (a.x() + c.x() ) /2,( a.y() + c.y() ) /2); QVector2D bc = QVector2D( (b.x() + c.x() ) /2,( b.y() + c.y() ) /2); divideTriangle(a, ab, ac, count-1); divideTriangle(b, bc, ab, count-1); divideTriangle(c, ac, bc, count-1); divideTriangle(ab, ac, bc, count-1); } else { triangle(a, b, c); } }
void divideTriangle(geometry* geom, const glm::vec3& a, glm::vec3& b, glm::vec3& c, int divisions) { if(divisions > 0) { glm::vec3 ab, ac, bc; ab = glm::normalize(glm::vec3(a + b) / glm::vec3(2.0f, 2.0f, 2.0f)); ac = glm::normalize(glm::vec3(a + c) / glm::vec3(2.0f, 2.0f, 2.0f)); bc = glm::normalize(glm::vec3(b + c) / glm::vec3(2.0f, 2.0f, 2.0f)); divideTriangle(geom, a, ab, ac, divisions - 1); divideTriangle(geom, ab, b, bc, divisions - 1); divideTriangle(geom, ac, bc, c, divisions - 1); divideTriangle(geom, ab, ac, bc, divisions - 1); } else triangle(geom, a, b, c); }
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // HW1b::setYesTwist // // Slot function to toggle yesTwist radioButton // void HW1b::setYesTwist() { m_twist = true; // populate m_points m_points.clear(); divideTriangle(m_init_points[0], m_init_points[1], m_init_points[2], m_subdivideSlider->value()); // redraw updateGL(); }
void divideTriangle(geometry* geom, const glm::vec3& a, glm::vec3& b, glm::vec3& c, int divisions) { if(divisions > 0) { glm::vec3 ab, ac, bc, abx, acx, bcx; glm::vec3 tempA, tempB, tempC; glm::vec3 radius = glm::vec3(1.0f, 1.0f, 1.0f); ab = glm::normalize(glm::vec3(a + b) / glm::vec3(2.0f, 2.0f, 2.0f)); ac = glm::normalize(glm::vec3(a + c) / glm::vec3(2.0f, 2.0f, 2.0f)); bc = glm::normalize(glm::vec3(b + c) / glm::vec3(2.0f, 2.0f, 2.0f)); divideTriangle(geom, a, ab, ac, divisions - 1); divideTriangle(geom, ab, b, bc, divisions - 1); divideTriangle(geom, ac, bc, c, divisions - 1); divideTriangle(geom, ab, ac, bc, divisions - 1); } else triangle(geom, a, b, c); }
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // HW3a::initVertexBuffer: // // Initialize vertex buffer. // void HW3a::initVertexBuffer() { // init geometry data const vec2 vertices[] = { vec2( 0.0f, 0.75f ), vec2( 0.65f, -0.375f), vec2(-0.65f, -0.375f) }; // add your code here // ...... divideTriangle(vertices[0], vertices[1], vertices[2], m_subdivisions); m_numPoints = m_points.size(); // save number of vertices static GLuint vertexBuffer = -1; glGenBuffers(1, &vertexBuffer); // bind the buffer to the GPU; all future drawing calls gets data from this buffer glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer); // copy the vertices from CPU to GPU glBufferData(GL_ARRAY_BUFFER, m_numPoints*sizeof(vec2), &m_points[0], GL_STATIC_DRAW); glVertexAttribPointer(ATTRIB_VERTEX, 2, GL_FLOAT, false, 0, NULL); glEnableVertexAttribArray(ATTRIB_VERTEX); //Create texture coordinates buffer static GLuint texCoordBuffer = -1; glGenBuffers(1, &texCoordBuffer); glBindBuffer(GL_ARRAY_BUFFER, texCoordBuffer); glBufferData(GL_ARRAY_BUFFER, m_numPoints*sizeof(vec2), &m_coords[0], GL_STATIC_DRAW); glVertexAttribPointer(ATTRIB_TEXTURE_POSITION, 2, GL_FLOAT, false, 0, NULL); glEnableVertexAttribArray(ATTRIB_TEXTURE_POSITION); m_points.clear(); m_coords.clear(); }
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // HW1b::setTheta: // // Slot function to change rotate angle. // void HW1b::setTheta(int angle) { // update slider and spinbox m_thetaSlider-> blockSignals(true); m_thetaSlider-> setValue(angle); m_thetaSlider-> blockSignals(false); m_thetaSpinBox-> blockSignals(true); m_thetaSpinBox-> setValue(angle); m_thetaSpinBox-> blockSignals(false); // convert angle to radians m_angle = angle * (M_PI / 180.); // populate m_points m_points.clear(); divideTriangle(m_init_points[0], m_init_points[1], m_init_points[2], m_subdivideSlider->value()); // redraw updateGL(); }