Integrate Assignment 1 Part B with Assignment 2a Part A, so that we can display
ID: 3727995 • Letter: I
Question
Integrate Assignment 1 Part B with Assignment 2a Part A, so that we can display the Sierpinski Gasket at the user's mouse positions. I can't seem to integrate them correctly, I am making the triangles on a callback button but its displaying random triangles rather than a serpinski gasket on the mouse click. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //Assignment 1B //Two-Dimensional Sierpinski Gasket // Generated using randomly selected vertices and bisection #include "GL/glew.h" #include <stdio.h> #include <stdlib.h> #include "GLFW/glfw3.h" const int NumPoints = 5000; //GLfloat points[NumPoints]; GLuint shader_programme; GLuint vao; //---------------------------------------------------------------------------- void init( void ) { GLuint vert_shader, frag_shader; /* GL shader programme object [combined, to link] */ // Specifiy the vertices for a triangle GLfloat vertices[] = { -1.0f, -1.0f, 0.0f, 1.0f, 1.0f, -1.0f }; GLfloat points[NumPoints*2]; points[0] = 0.25; points[1] = 0.5; for (int i = 2; i < NumPoints*2; i+=2) { int j = rand()%3; // pick a vertex at random // Compute the point halfway between the selected vertex // and the previous point points[i] = (points[i - 2] + vertices[2*j]) / 2.0; points[i+1] = (points[i - 1] + vertices[2 * j+1]) / 2.0; } // Create and initialize a buffer object GLuint buffer; glGenBuffers( 1, &buffer ); glBindBuffer( GL_ARRAY_BUFFER, buffer ); glBufferData( GL_ARRAY_BUFFER, sizeof(points), points, GL_STATIC_DRAW ); // Create a vertex array object glGenVertexArrays(1, &vao); glBindVertexArray(vao); glEnableVertexAttribArray(0); glBindBuffer(GL_ARRAY_BUFFER, buffer); // "attribute #0 is created from every 2 variables in the above buffer, of type // float (i.e. make me vec2s)" glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, NULL); // Load shaders and use the resulting shader program const char *vertex_shader = "#version 410 " "in vec4 vPosition;" "void main () {" " gl_Position = vPosition;" "}"; /* the fragment shader colours each fragment (pixel-sized area of the triangle) */ const char *fragment_shader = "#version 410 " "out vec4 FragColor;" "void main () {" " FragColor = vec4( 1.0, 0.0, 0.0, 1.0 );" "}"; vert_shader = glCreateShader(GL_VERTEX_SHADER); glShaderSource(vert_shader, 1, &vertex_shader, NULL); glCompileShader(vert_shader); frag_shader = glCreateShader(GL_FRAGMENT_SHADER); glShaderSource(frag_shader, 1, &fragment_shader, NULL); glCompileShader(frag_shader); shader_programme = glCreateProgram(); glAttachShader(shader_programme, frag_shader); glAttachShader(shader_programme, vert_shader); glLinkProgram(shader_programme); } //---------------------------------------------------------------------------- int main( int argc, char **argv ) { GLFWwindow *window = NULL; const GLubyte *renderer; const GLubyte *version; /* start GL context and O/S window using the GLFW helper library */ if (!glfwInit()) { fprintf(stderr, "ERROR: could not start GLFW3 "); return 1; } /* We must specify 3.2 core if on Apple OS X -- other O/S can specify anything here. I defined 'APPLE' in the makefile for OS X Remove the #ifdef #endif and play around with this - you should be starting an explicit version anyway, and some non-Apple drivers will require this too. */ //#ifdef APPLE glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 2); glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); //#endif window = glfwCreateWindow(640, 480, "Sierpinski Gasket", NULL, NULL); if (!window) { fprintf(stderr, "ERROR: could not open window with GLFW3 "); glfwTerminate(); return 1; } glfwMakeContextCurrent(window); /* start GLEW extension handler */ glewExperimental = GL_TRUE; glewInit(); renderer = glGetString(GL_RENDERER); /* get renderer string */ version = glGetString(GL_VERSION); /* version as a string */ printf("Renderer: %s ", renderer); printf("OpenGL version supported %s ", version); init(); do{ glClear(GL_COLOR_BUFFER_BIT); // clear the window glUseProgram(shader_programme); glBindVertexArray(vao); glDrawArrays(GL_POINTS, 0, NumPoints ); // draw the points /* update other events like input handling */ glfwPollEvents(); glfwSwapBuffers(window); } while (!glfwWindowShouldClose(window)); // Close OpenGL window and terminate GLFW glfwTerminate(); return 0; } ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Assignment 2A Part A // DrawSquare.cpp // Generate a square on a solid background at user’s mouse position #include "GL/glew.h" #include <stdio.h> #include <stdlib.h> #include "GLFW/glfw3.h" GLuint shader_programme; GLuint vao; GLfloat points[200]; int w; int i = 6; GLfloat size = 20; int cnt = 3; GLuint buffer; //---------------------------------------------------------------------------- void init( void ) { GLuint vert_shader, frag_shader; /* GL shader programme object [combined, to link] */ // Specifiy the vertices for a triangle //GLfloat points[] = { -0.5, 0.5, 0.5, 0.5, 0.0, -0.5 }; // Create and initialize a buffer object glGenBuffers( 1, &buffer ); glBindBuffer( GL_ARRAY_BUFFER, buffer ); glBufferData( GL_ARRAY_BUFFER, sizeof(points), points, GL_STATIC_DRAW ); // Create a vertex array object glGenVertexArrays(1, &vao); glBindVertexArray(vao); glEnableVertexAttribArray(0); glBindBuffer(GL_ARRAY_BUFFER, buffer); // "attribute #0 is created from every 2 variables in the above buffer, of type // float (i.e. make me vec2s)" glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, NULL); // Load shaders and use the resulting shader program const char *vertex_shader = "#version 410 " "in vec4 vPosition;" "void main () {" " gl_Position = vPosition;" "}"; /* the fragment shader colours each fragment (pixel-sized area of the triangle) */ const char *fragment_shader = "#version 410 " "out vec4 FragColor;" "void main () {" " FragColor = vec4( 1.0, 0.0, 0.0, 1.0 );" "}"; vert_shader = glCreateShader(GL_VERTEX_SHADER); glShaderSource(vert_shader, 1, &vertex_shader, NULL); glCompileShader(vert_shader); frag_shader = glCreateShader(GL_FRAGMENT_SHADER); glShaderSource(frag_shader, 1, &fragment_shader, NULL); glCompileShader(frag_shader); shader_programme = glCreateProgram(); glAttachShader(shader_programme, frag_shader); glAttachShader(shader_programme, vert_shader); glLinkProgram(shader_programme); } void drawSquare(int x, int y) { //y = w - y; /* invert y position */ points[i] = (2.0f * (x+size) / w )- 1.0f; points[i + 1] = 1.0f - (2.0f * (y+size)) / w;; points[i + 2] = (2.0f * (x - size) / w) - 1.0f; points[i + 3] = 1.0f - (2.0f * (y + size)) / w;; points[i + 4] = (2.0f * (x + size) / w) - 1.0f; points[i + 5] = 1.0f - (2.0f * (y - size)) / w;; points[i + 6] = (2.0f * (x - size) / w) - 1.0f; points[i + 7] = 1.0f - (2.0f * (y + size)) / w;; points[i + 8] = (2.0f * (x + size) / w) - 1.0f; points[i + 9] = 1.0f - (2.0f * (y - size)) / w;; points[i + 10] = (2.0f * (x - size) / w) - 1.0f; points[i + 11] = 1.0f - (2.0f * (y - size)) / w; //points[i] = -0.5; //points[i + 1] = 0.5; //points[i + 2] = 0.5; //points[i + 3] = 0.5; //points[i + 4] = 0.0; //points[i + 5] = -0.5; //points[i + 6] = 0; //points[i + 7] = 0; //points[i + 8] = 0; //points[i + 9] = 0; //points[i + 10] = 0; //points[i + 11] = 0; i += 12; cnt+=6; } void mymouse(GLFWwindow* window, int button, int action, int mods){ if (GLFW_PRESS == action) { double x, y; glfwGetCursorPos(window, &x, &y); drawSquare(x, y); //glGenBuffers(1, &buffer); glBindBuffer(GL_ARRAY_BUFFER, buffer); glBufferData(GL_ARRAY_BUFFER, sizeof(points), points, GL_STATIC_DRAW); //glGenVertexArrays(1, &vao); glBindBuffer(GL_ARRAY_BUFFER, buffer); // "attribute #0 is created from every 2 variables in the above buffer, of type // float (i.e. make me vec2s)" glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, NULL); } } //---------------------------------------------------------------------------- int main( int argc, char **argv ) { GLFWwindow *window = NULL; const GLubyte *renderer; const GLubyte *version; /* start GL context and O/S window using the GLFW helper library */ if (!glfwInit()) { fprintf(stderr, "ERROR: could not start GLFW3 "); return 1; } /* We must specify 3.2 core if on Apple OS X -- other O/S can specify anything here. I defined 'APPLE' in the makefile for OS X Remove the #ifdef #endif and play around with this - you should be starting an explicit version anyway, and some non-Apple drivers will require this too. */ #ifdef APPLE glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 2); glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); #endif window = glfwCreateWindow(640, 640, "simple", NULL, NULL); w = 640; if (!window) { fprintf(stderr, "ERROR: could not open window with GLFW3 "); glfwTerminate(); return 1; } glfwMakeContextCurrent(window); /* start GLEW extension handler */ glewExperimental = GL_TRUE; glewInit(); renderer = glGetString(GL_RENDERER); /* get renderer string */ version = glGetString(GL_VERSION); /* version as a string */ printf("Renderer: %s ", renderer); printf("OpenGL version supported %s ", version); init(); glfwSetMouseButtonCallback(window, mymouse); do{ glClear(GL_COLOR_BUFFER_BIT); // clear the window glUseProgram(shader_programme); glBindVertexArray(vao); glDrawArrays(GL_TRIANGLES, 0, cnt ); // draw the points /* update other events like input handling */ glfwPollEvents(); glfwSwapBuffers(window); } while (!glfwWindowShouldClose(window)); // Close OpenGL window and terminate GLFW glfwTerminate(); return 0; } ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
Explanation / Answer
#include <windows.h>
#include <GL/glut.h>
#include <cstdlib>
#include <ctime>
// menu item
#define MENU_SMOOTH 1
#define MENU_FLAT 0
// Function prototypes
void generateColors();
double random(bool reset = false);
void drawPyramid(GLfloat *a, GLfloat *b, GLfloat *c, GLfloat *d);
void dividePyramid(GLfloat *a, GLfloat *b, GLfloat *c, GLfloat *d, int iteraciones);
void keyboard(unsigned char key, int x, int y);
void special(int key, int x, int y);
void mouse(int button, int state, int x, int y);
void menu(int item);
void display();
void doZoom();
void init();
GLfloat pyramid[4][3] = {{-1.0, -1.0, -1.0},
{ 1.0, -1.0, -1.0},
{ 0.0, -1.0, 0.732},
{ 0.0, 1.0, -0.134}};
double colors[1000] = {0};
double angle = 0;
int iterations = 5;
double zoom = 0;
int shading = GL_SMOOTH;
void generateColors() {
for (int i = 0; i < 1000; i++) {
colors[i] = rand() / (double) RAND_MAX;
}
}
double random(bool reset) {
static int curr = 0;
if (reset) {
curr = 0;
return 0.0;
} else {
if (curr >= 1000) curr = 0;
return colors[curr++];
}
}
void drawPyramid(GLfloat *a, GLfloat *b, GLfloat *c, GLfloat *d) {
glPolygonMode(GL_FRONT_AND_BACK,GL_FILL);
glShadeModel(shading);
// bottom
glBegin(GL_TRIANGLES);
//en este caso los vértices están dados en el sentido de las manecillas del reloj
glColor3f(random(), random(), random());
glVertex3fv(a);
glColor3f(random(), random(), random());
glVertex3fv(b);
glColor3f(random(), random(), random());
glVertex3fv(c);
glEnd();
glBegin(GL_TRIANGLES);
glColor3f(random(), random(), random());
glVertex3fv(a);
glColor3f(random(), random(), random());
glVertex3fv(b);
glColor3f(random(), random(), random());
glVertex3fv(d);
glEnd();
glBegin(GL_TRIANGLES);
glColor3f(random(), random(), random());
glVertex3fv(a);
glColor3f(random(), random(), random());
glVertex3fv(c);
glColor3f(random(), random(), random());
glVertex3fv(d);
glEnd();
glBegin(GL_TRIANGLES);
glColor3f(random(), random(), random());
glVertex3fv(b);
glColor3f(random(), random(), random());
glVertex3fv(c);
glColor3f(random(), random(), random());
glVertex3fv(d);
glEnd();
}
void dividePyramid(GLfloat *a, GLfloat *b, GLfloat *c, GLfloat *d, int iteraciones) {
GLfloat v[6][3];
int j;
if (iteraciones > 0) {
//encontrar los puntos medios de cada arista del triángulo
for (j = 0; j < 3; j++) {
v[0][j] = (a[j] + b[j]) / 2;
}
for (j = 0; j < 3; j++) {
v[1][j] = (a[j] + c[j]) / 2;
}
for (j = 0; j < 3; j++) {
v[2][j] = (b[j] + c[j]) / 2;
}
for (j = 0; j < 3; j++) {
v[3][j] = (a[j] + d[j]) / 2;
}
for (j = 0; j < 3; j++) {
v[4][j] = (b[j] + d[j]) / 2;
}
for (j = 0; j < 3; j++) {
v[5][j] = (c[j] + d[j]) / 2;
}
//por cada triángulo que entra, se crean 4 triángulos más pequeños y recursivamente estos se dividen a su vez
dividePyramid( a , v[0], v[1], v[3], iteraciones-1);
dividePyramid(v[0], b , v[2], v[4], iteraciones-1);
dividePyramid(v[1], v[2], c , v[5], iteraciones-1);
dividePyramid(v[3], v[4], v[5], d , iteraciones-1);
// commenting this will create a Sierpinski Triangle
//divideTriangle(v[0], v[1], v[2], iteraciones-1);
} else {
//dibujar el triángulo de la iteración 0
drawPyramid(a, b, c, d);
}
}
void keyboard(unsigned char key, int x, int y) {
switch (key) {
case '+':
if (iterations < 10) iterations += 1;
display();
break;
case '-':
if (iterations > 0) iterations -= 1;
display();
break;
case 'q':
exit(0);
break;
}
}
void special(int key, int x, int y) {
switch (key) {
case GLUT_KEY_UP:
if (zoom - 0.1 > -1) zoom -= 0.05;
doZoom();
break;
case GLUT_KEY_DOWN:
zoom += 0.05;
doZoom();
break;
}
}
void mouse(int button, int state, int x, int y) {
if (state == GLUT_UP) {
generateColors();
display();
}
}
void menu(int item) {
switch (item) {
case MENU_FLAT:
shading = GL_FLAT;
display();
break;
case MENU_SMOOTH:
shading = GL_SMOOTH;
display();
break;
}
}
void doZoom() {
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(-1.0 - zoom, 1.0 + zoom, -1.0 - zoom, 1.0 + zoom, -20.0, 20.0);
glMatrixMode(GL_MODELVIEW);
display();
}
void display() {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glPushMatrix();
glRotatef(angle, 0, 1, 0);
random(true);
//al llamar la función dividirTriangulo se indica como cuarto parámetro el número de iteraciones de subdivisión que se quieren
dividePyramid(pyramid[0], pyramid[1], pyramid[2], pyramid[3], iterations);
glPopMatrix();
glFlush();
glutPostRedisplay();
}
void init() {
glClearColor(0.0, 0.0, 0.0, 1.0);
glColor3f(0.0, 0.0, 0.0);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(-2.0, 2.0, -2.0, 2.0, -20.0, 20.0);
glEnable(GL_DEPTH_TEST);
}
void idle() {
angle += 0.01;
if (angle > 360) angle = 0;
}
int main(int argc, char** argv) {
srand(time(NULL));
generateColors();
glutInitDisplayMode(GLUT_RGB);
glutInitWindowSize(600, 600);
glutInitWindowPosition(0, 0);
glutCreateWindow("Sierpinski Triangle");
glutPositionWindow(100, 100);
glutKeyboardFunc(keyboard);
glutSpecialFunc(special);
glutMouseFunc(mouse);
glutCreateMenu(menu);
glutAddMenuEntry("Smooth shading", MENU_SMOOTH);
glutAddMenuEntry("Flat shading", MENU_FLAT);
glutAttachMenu(GLUT_RIGHT_BUTTON);
init();
glutDisplayFunc(display);
glutIdleFunc(idle);
glutMainLoop();
}
triangle.cpp
#include <windows.h>
#include <GL/glut.h>
#include <cstdlib>
#include <ctime>
// menu item
#define MENU_SMOOTH 1
#define MENU_FLAT 0
// Function prototypes
void generateColors();
double random(bool reset = false);
void drawTriangle(GLfloat *a, GLfloat *b, GLfloat *c);
void divideTriangle(GLfloat *a, GLfloat *b, GLfloat *c, int iteraciones);
void keyboard(unsigned char key, int x, int y);
void special(int key, int x, int y);
void mouse(int button, int state, int x, int y);
void menu(int item);
void display();
void doZoom();
void init();
//coordenadas del triángulo que se dividirá
GLfloat triangle[3][2] = {{-1.0, -1.0},
{ 0.0, 1.0},
{ 1.0, -1.0}};
double colors[1000] = {0};
int iterations = 5;
double zoom = 0;
int shading = GL_SMOOTH;
void generateColors() {
for (int i = 0; i < 1000; i++) {
colors[i] = rand() / (double) RAND_MAX;
}
}
double random(bool reset) {
static int curr = 0;
if (reset) {
curr = 0;
return 0.0;
} else {
if (curr >= 1000) curr = 0;
return colors[curr++];
}
}
void drawTriangle(GLfloat *a, GLfloat *b, GLfloat *c) {
glPolygonMode(GL_FRONT_AND_BACK,GL_FILL);
glShadeModel(shading);
glBegin(GL_TRIANGLES);
//en este caso los vértices están dados en el sentido de las manecillas del reloj
glColor3f(random(), random(), random());
glVertex2fv(a);
glColor3f(random(), random(), random());
glVertex2fv(b);
glColor3f(random(), random(), random());
glVertex2fv(c);
glEnd();
}
void divideTriangle(GLfloat *a, GLfloat *b, GLfloat *c, int iteraciones) {
GLfloat v[3][2];
int j;
if (iteraciones > 0) {
//encontrar los puntos medios de cada arista del triángulo
for (j = 0; j < 2; j++) {
v[0][j] = (a[j] + b[j]) / 2;
}
for (j = 0; j < 2; j++) {
v[1][j] = (a[j] + c[j]) / 2;
}
for (j = 0; j < 2; j++) {
v[2][j] = (b[j] + c[j]) / 2;
}
//por cada triángulo que entra, se crean 4 triángulos más pequeños y recursivamente estos se dividen a su vez
divideTriangle( a , v[0], v[1], iteraciones-1);
divideTriangle(v[0], b , v[2], iteraciones-1);
divideTriangle(v[1], v[2], c , iteraciones-1);
// commenting this will create a Sierpinski Triangle
//divideTriangle(v[0], v[1], v[2], iteraciones-1);
} else {
//dibujar el triángulo de la iteración 0
drawTriangle(a,b,c);
}
}
void keyboard(unsigned char key, int x, int y) {
switch (key) {
case '+':
if (iterations < 10) iterations += 1;
display();
break;
case '-':
if (iterations > 0) iterations -= 1;
display();
break;
case 'q':
exit(0);
break;
}
}
void special(int key, int x, int y) {
switch (key) {
case GLUT_KEY_UP:
if (zoom - 0.1 > -1) zoom -= 0.05;
doZoom();
break;
case GLUT_KEY_DOWN:
zoom += 0.05;
doZoom();
break;
}
}
void mouse(int button, int state, int x, int y) {
if (state == GLUT_UP) {
generateColors();
display();
}
}
void menu(int item) {
switch (item) {
case MENU_FLAT:
shading = GL_FLAT;
display();
break;
case MENU_SMOOTH:
shading = GL_SMOOTH;
display();
break;
}
}
void doZoom() {
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(-1.0 - zoom, 1.0 + zoom, -1.0 - zoom, 1.0 + zoom);
glMatrixMode(GL_MODELVIEW);
display();
}
void display() {
glClear(GL_COLOR_BUFFER_BIT);
random(true);
//al llamar la función dividirTriangulo se indica como cuarto parámetro el número de iteraciones de subdivisión que se quieren
divideTriangle(triangle[0], triangle[1], triangle[2], iterations);
glFlush();
}
void init() {
glClearColor(0.0, 0.0, 0.0, 1.0);
glColor3f(0.0, 0.0, 0.0);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(-1.0, 1.0, -1.0, 1.0);
}
int main(int argc, char** argv) {
srand(time(NULL));
generateColors();
glutInitDisplayMode(GLUT_RGB);
glutInitWindowSize(600, 600);
glutInitWindowPosition(0, 0);
glutCreateWindow("Sierpinski Triangle");
glutPositionWindow(100, 100);
glutKeyboardFunc(keyboard);
glutSpecialFunc(special);
glutMouseFunc(mouse);
glutCreateMenu(menu);
glutAddMenuEntry("Smooth shading", MENU_SMOOTH);
glutAddMenuEntry("Flat shading", MENU_FLAT);
glutAttachMenu(GLUT_RIGHT_BUTTON);
init();
glutDisplayFunc(display);
glutMainLoop();
}
Related Questions
drjack9650@gmail.com
Navigate
Integrity-first tutoring: explanations and feedback only — we do not complete graded work. Learn more.