23At the lowest level of processing we manipulate bits in th

2.3At the lowest level of processing, we manipulate bits in the framebuffer. In WebGL, we can create a virtual framebuffer in our application as a two- dimensional array. You can experiment with simple raster algorithms, such as drawing lines or circles, through a function that generates a single value in the array. Write a small library that will allow you to work in a virtual frame- buffer that you create in memory. The core functions should be WritePixel and ReadPixel. Your library should allow you to set up and display your vir- tual framebuffer and to run a user program that reads and writes pixels using gl.POINTS in gl.drawArrays. 2.4 Turtle graphics is an alternative positioning system that is based on the concept of a turtle moving around the screen with a pen attached to the bottom of its shell. The turtle’s position can be described by a triplet (x, y, ), giving the location of the center and the orientation of the turtle. A typical API for such a system includes functions such as the following: init(x,y,theta); // initialize position and orientation of turtle forward(distance); right(angle); left(angle); pen(up_down); Implement a turtle graphics library using WebGL.

Solution

//2.4 program

turtle.cpp


#include \"turtle.hpp\"
#include <math.h>

GLfloat c = M_PI/180.0;
void Turtle::init(double x, double y, double theta) {
    m_startx = x;
    m_starty = y;
    m_theta = theta;
}

void Turtle::forward(double distance) {
    if (m_drawing) {
//        glClear(GL_COLOR_BUFFER_BIT);
        glBegin(GL_LINES);
        glVertex2f(m_startx, m_starty);
        glVertex2f(m_startx+distance*cos(m_theta), m_starty+distance*sin(m_theta));
        glEnd();
        glFlush();
    }
  
    m_startx+= distance*cos(m_theta);
    m_starty+= distance*sin(m_theta);
}

void Turtle::right(double angle) {
    m_theta-=angle;
    if (m_theta < 0.0) {
        m_theta+=360.0;
    }
}

void Turtle::left(double angle) {
    m_theta+=angle;
    if (m_theta > 360.0) {
        m_theta-=360.0;
    }
}

void Turtle::pen(bool up_down) {
    if (up_down) {
        m_drawing = true;
    }
    else m_drawing = false;
}

Turtle* tur = new Turtle();
void display() {
    glClear(GL_COLOR_BUFFER_BIT);
    tur->init(0.0, 0.0, 0);
    tur->pen(true);
    tur->forward(50);
    tur->pen(false);
    tur->left(90*c);
    tur->forward(50);
    tur->pen(true);
    tur->right(75*c);
    tur->forward(50);
}

void myReshape(int w, int h) {
    glViewport(0, 0, w, h);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    if (w <= h)
        glOrtho(-200.0, 200.0, -200.0*(GLfloat)h/(GLfloat)w, 200.0*(GLfloat)h/(GLfloat)w,-10.0, 10.0);
    else
        glOrtho(-200.0*(GLfloat)h/(GLfloat)w, 200.0*(GLfloat)h/(GLfloat)w, -200.0, 200.0, -10.0, 10.0);
    glMatrixMode(GL_MODELVIEW);
    glutPostRedisplay();
}

int main(int argc, char ** argv) {
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
    glutInitWindowSize(500,500);
    glutInitWindowPosition(0, 0);
    glutCreateWindow(\"Xcode Glut Demo\");
    glutReshapeFunc(myReshape);
    glutDisplayFunc(display);
    glutMainLoop();
    glClearColor(1.0, 1.0, 1.0, 1.0);
    glColor3f(0.0,0.0,0.0);
    glClear(GL_COLOR_BUFFER_BIT);
  
//    glMatrixMode(GL_PROJECTION);
//    glLoadIdentity();
//    gluOrtho2D(0.0, 50.0, 0.0, 50.0);
//    glMatrixMode(GL_MODELVIEW);

    return 0;
  
}


turtle.hpp


#ifndef turtle_hpp
#define turtle_hpp

#include <stdio.h>
#include <GLUT/GLUT.h>

class Turtle {
public:
    Turtle(){};
    ~Turtle(){};
  
    void init(double x, double y, double theta);
    void forward(double distance);
    void right(double angle);
    void left(double angle);
    void pen(bool up_down);
private:
    double m_startx = 0.0;
    double m_starty = 0.0;
    double m_theta = 0.0;
    bool m_drawing = false;
};
#endif /* turtle_hpp */


//2.3 program

test.cpp


#include \"test.hpp\"
#include \"miniOpenglToolkit.hpp\"
#include <GLUT/GLUT.h>
#include <math.h>
#include <iostream>

#define max(a, b) a>b?a:b
GLint mWidth = 640;
GLint mHeight = 640;

MiniOpenglToolkit* mot = new MiniOpenglToolkit();

inline void swap_int(int *a, int *b) {
    *a ^= *b;
    *b ^= *a;
    *a ^= *b;
}

void drawLineWithEquation(int x0, int y0, int xEnd, int yEnd) {
    float m = (float)(yEnd-y0)/(xEnd-x0);
    float mr = 1/m;
    if (m <= 1) {
        for (int x = x0; x <= xEnd; ++x) {
            int y = lroundf((x-x0)*m+y0);
            mot->writePixel(x, y);
        }
    }
    else {
        for (int y = y0; y <= yEnd; ++y) {
            int x = lroundf((y-y0)*mr+x0);
            mot->writePixel(x, y);
        }
    }
}

void drawLineWithDDA(int x0, int y0, int xEnd, int yEnd) {
    int dx = xEnd-x0;
    int dy = yEnd-y0;
    float x = x0;
    float y = y0;
    int steps = max(std::abs(dx), std::abs(dy));
  
    float xIncrement = (float)(dx)/steps;
    float yIncrement = (float)(dy)/steps;
  
    mot->writePixel(x, y);
  
    for (int i = 0; i <= steps; ++i) {
        x += xIncrement;
        y += yIncrement;
        mot->writePixel(lroundf(x), lroundf(y));
    }
}

void drawLineWithBresenham(int x0, int y0, int xEnd, int yEnd) {
    int dx = abs(xEnd-x0),
        dy = abs(yEnd-y0),
        yy = 0;
    if (dx < dy) {
        yy = 1;
        swap_int(&x0, &y0);
        swap_int(&xEnd, &yEnd);
        swap_int(&dx, &dy);
    }
  
    int ix = (xEnd-x0)>0?1:-1,
        iy = (yEnd-y0)>0?1:-1,
        cx = x0,
        cy = y0,
        n2dy = dy*2,
        n2dydx = (dy-dx)*2,
        d = dy*2-dx;
    if (yy) {
        while(cx != xEnd) {
            if (d < 0) {
                d += n2dy;
            } else {
                cy+=iy;
                d += n2dydx;
            }
            mot->writePixel(cy, cx);
            cx += ix;
        }
    }else { //x45
        while(cx != xEnd) {
            if (d < 0) {
                d += n2dy;
            } else {
                cy += iy;
                d += n2dydx;
            }
            mot->writePixel(cx, cy);
            cx += ix;
        }
    }
}
void _draw_circle_8(int xc, int yc, int x, int y) {
    mot->writePixel(xc+x, yc+y);
    mot->writePixel(xc-x, yc+y);
    mot->writePixel(xc+x, yc-y);
    mot->writePixel(xc-x, yc-y);
    mot->writePixel(xc+y, yc+x);
    mot->writePixel(xc-y, yc+x);
    mot->writePixel(xc+y, yc-x);
    mot->writePixel(xc-y, yc-x);
}
void drawCircleWithBresenham(int xc, int yc, int r, int fill) {
  
  
    if (xc + r < 0 || xc -r >= mWidth || yc + r < 0 || yc - r >= mHeight) return;
  
    int x = 0, y = r, yi, d;
    d = 3-2*r;
  
    if (fill) {
        while(x <= y) {
            for (yi = x; yi <= y; yi++) {
                _draw_circle_8(xc, yc, x, yi);
            }
          
            if (d < 0) {
                d = d+4*x+6;
            } else {
                d = d+4*(x-y)+10;
                y--;
            }
            x++;
        }
    } else {
        while(x <= y) {
            _draw_circle_8(xc, yc, x, y);
            if (d < 0) {
                d = d+4*x+6;
            } else {
                d = d+4*(x-y)+10;
                y--;
            }
            x++;
        }
    }
}

void display() {
    mot->clear();
//    drawLineWithEquation(0, 0, 300, 50);
//    drawLineWithEquation(0, 0, 300, 100);
//    drawLineWithEquation(0, 0, 300, 150);
//    drawLineWithEquation(0, 0, 300, 300);
//    drawLineWithEquation(0, 0, 150, 300);
//    drawLineWithEquation(0, 0, 100, 300);
//    drawLineWithEquation(0, 0, 50, 300);
//    drawLineWithEquation(300,0,300,50);
//    drawLineWithDDA(0,0,0,300);
    drawLineWithBresenham(0, 0, 0, 300);
    drawCircleWithBresenham(0, 0, 300, 0);
  
  
    mot->flush();
}

int main(int argc, char ** argv) {
    mot->init(argc, argv);
    mot->readPixel(mWidth,mHeight);
    mot->displayFunc(display);
    mot->mainLoop();
    return 0;
  
}


test.hpp

#ifndef test_hpp
#define test_hpp

#include <stdio.h>

#endif /* test_hpp */


miniOpenglToolkit.cpp

#include \"miniOpenglToolkit.hpp\"

void MiniOpenglToolkit::init(int argc, char ** argv) {
    glutInit(&argc, argv);
}

MiniOpenglToolkit::MiniOpenglToolkit():defaultWidth(1),defaultHeight(1),defaultFormat(GL_BLUE),defaultType(GL_UNSIGNED_BYTE),defaultPixels(nullptr){}

void MiniOpenglToolkit::readPixel(GLint width, GLint height) {
    glutInitWindowSize(width, height);
    glutInitWindowPosition(200, 200);
    glutCreateWindow(\"Draw Line\");
    glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
    glClearColor(1.0,1.0,1.0,1.0);
    glColor3f(0.0, 0.0,0.0);
  
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    gluOrtho2D(-width/2, width/2, -height/2, height/2);
    glMatrixMode(GL_MODELVIEW);
    glEnableClientState(GL_VERTEX_ARRAY);
}

void MiniOpenglToolkit::writePixel(GLint x, GLint y) {
    glBegin(GL_POINTS);
    GLint vertices[] = {x,y};
    glVertex2iv(vertices);
    glEnd();
}

GLvoid* MiniOpenglToolkit::getPixels() {
    return this->defaultPixels;
}

void MiniOpenglToolkit::mainLoop() {
    glutMainLoop();
}

void MiniOpenglToolkit::displayFunc(void (*func)()) {
    glutDisplayFunc(func);
}

void MiniOpenglToolkit::reshape() {
    glutReshapeFunc([](int width, int height) {
        glMatrixMode(GL_PROJECTION);
        glLoadIdentity();
        gluOrtho2D(-width/2, width/2, 0, height);
        glMatrixMode(GL_MODELVIEW);
    });
}

void MiniOpenglToolkit::flush() {
    glFlush();
}

void MiniOpenglToolkit::clear() {
    glClear(GL_COLOR_BUFFER_BIT);
}


miniOpenglToolkit.hpp


#ifndef miniOpenglToolkit_hpp
#define miniOpenglToolkit_hpp

#include <stdio.h>
#include <GLUT/GLUT.h>

class MiniOpenglToolkit
{
public:
  
    MiniOpenglToolkit();
    ~MiniOpenglToolkit(){};
    void readPixel(GLint width, GLint height);
  
    void writePixel(GLint x, GLint y);
  
    GLvoid* getPixels();
  
    void init(int argc, char ** argv);
  
    void mainLoop();
  
    void displayFunc(void (*func)(void));
  
    /**
     @brief reshape func
     */
    void reshape();
    /**
     @brief flush
     */
    void flush();
  
    /**
     @brief clear
     */
    void clear();
private:
    GLsizei defaultWidth;
    GLsizei defaultHeight;
    GLenum defaultFormat;
    GLenum defaultType;
    GLvoid* defaultPixels;
};
#endif /* miniOpenglToolkit_hpp */

2.3At the lowest level of processing, we manipulate bits in the framebuffer. In WebGL, we can create a virtual framebuffer in our application as a two- dimensio
2.3At the lowest level of processing, we manipulate bits in the framebuffer. In WebGL, we can create a virtual framebuffer in our application as a two- dimensio
2.3At the lowest level of processing, we manipulate bits in the framebuffer. In WebGL, we can create a virtual framebuffer in our application as a two- dimensio
2.3At the lowest level of processing, we manipulate bits in the framebuffer. In WebGL, we can create a virtual framebuffer in our application as a two- dimensio
2.3At the lowest level of processing, we manipulate bits in the framebuffer. In WebGL, we can create a virtual framebuffer in our application as a two- dimensio
2.3At the lowest level of processing, we manipulate bits in the framebuffer. In WebGL, we can create a virtual framebuffer in our application as a two- dimensio
2.3At the lowest level of processing, we manipulate bits in the framebuffer. In WebGL, we can create a virtual framebuffer in our application as a two- dimensio

Get Help Now

Submit a Take Down Notice

Tutor
Tutor: Dr Jack
Most rated tutor on our site