Search code examples
c++openglglewfreeglut

Drawing letters using triangles in OpenGL?


I'm required to draw my name using triangles. I understand how to handle shaders. I am just confused on how to actual draw the objects and connect them to make a letter.

I've been given some code to work with:

#include "Angel.h"

const int NumPoints = 50000;


/*This function initializes an array of 3d vectors 
   and sends it to the graphics card along with shaders
   properly connected to them.*/

void
init( void )
{
    vec3 points[NumPoints];

    // Specifiy the vertices for a triangle
    vec3 vertices[] = {
        vec3( -1.0, -1.0, 0.0 ),
        vec3(  0.0,  1.0, 0.0 ),
        vec3(  1.0, -1.0, 0.0 )
    };

    // Select an arbitrary initial point inside of the triangle
    points[0] = vec3( 0.0, 1.0, 0.0 );

    // compute and store NumPoints - 1 new points
    for ( int i = 1; i < NumPoints; ++i ) {
        int j = rand() % 3;   // pick a vertex from the triangle at random

        // Compute the point halfway between the selected vertex
        //   and the previous point
        points[i] = ( points[i - 1] + vertices[j] ) / 2.0;
    }

    // Create a vertex array object
    GLuint vao;  //just an integer recognized by graphics card
    glGenVertexArrays( 1, &vao ); //generate 1 buffer
    glBindVertexArray( vao ); //become array buffer

    // Create and initialize a buffer object //sends it to graphics card
    GLuint buffer;
    glGenBuffers( 1, &buffer );
    glBindBuffer( GL_ARRAY_BUFFER, buffer );
    glBufferData( GL_ARRAY_BUFFER, sizeof(points), points, GL_STATIC_DRAW ); //size of array glstatic draw means this point isnt gonna change its static

   // Load shaders and use the resulting shader program

    GLuint program = InitShader("simpleShader - Copy.vert", "simpleShader - Copy.frag");
    // make these shaders the current shaders
    glUseProgram( program );

    // Initialize the vertex position attribute from the vertex shader
    GLuint loc = glGetAttribLocation( program, "vPosition" ); //find the location in the code
    glEnableVertexAttribArray( loc );
    glVertexAttribPointer( loc, 3, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(0) );

    glClearColor( 0.5, 0.5, 0.5, 1.0 ); // gray background
}

//----------------------------------------------------------------------------
/* This function handles the display and it is automatically called by GLUT
   once it is declared as the display function. The application should not
   call it directly.
*/

void
display( void )
{
    glClear( GL_COLOR_BUFFER_BIT );             // clear the window
    glDrawArrays( GL_POINTS, 0, NumPoints );    // draw the points
    glFlush();                                  // flush the buffer
}

//----------------------------------------------------------------------------
/* This function handles the keyboard and it is called by GLUT once it is 
   declared as the keyboard function. The application should not call it
   directly.
*/

void
keyboard( unsigned char key, int x, int y )
{
    switch ( key ) {
    case 033:                   // escape key
        exit( EXIT_SUCCESS );   // terminates the program
        break;
    }
}

//----------------------------------------------------------------------------
/* This is the main function that calls all the functions to initialize
   and setup the OpenGL environment through GLUT and GLEW.
*/

int
main( int argc, char **argv )
{
    // Initialize GLUT
    glutInit( &argc, argv );
    // Initialize the display mode to a buffer with Red, Green, Blue and Alpha channels
    glutInitDisplayMode( GLUT_RGBA );
    // Set the window size
    glutInitWindowSize( 512, 512 );
    // Here you set the OpenGL version
    glutInitContextVersion( 3, 2 );
    //Use only one of the next two lines
    //glutInitContextProfile( GLUT_CORE_PROFILE );
    glutInitContextProfile( GLUT_COMPATIBILITY_PROFILE );
    glutCreateWindow( "Simple GLSL example" );

    // Uncomment if you are using GLEW
    glewInit(); 

    // initialize the array and send it to the graphics card
    init();

    // provide the function that handles the display
    glutDisplayFunc( display );
    // provide the functions that handles the keyboard
    glutKeyboardFunc( keyboard );
    glutMainLoop();
    return 0;
}

Solution

  • It looks like your problem is intended to familiarize you with setting up and using a vertex buffer. If so, it doesn't matter how you come up with the triangles -- the point is to understand how the setup works.

    So, the first thing you need to do is to read your textbook on this topic. If you don't have a text, you will need to look up the graphics calls in an OpenGL reference.

    If you run the program as-is, it should draw a bunch of randomly chosen, disconnected points (in the form of a fractal, but still...). This is because the actual draw call, glDrawArrays(), is called with the enumerated value GL_POINTS, which tells it to draw points, as its first argument.

    If you read the documentation for glDrawArrays(), it should list other values for this argument, some of which draw triangles in various ways. The most straightforward of these is GL_TRIANGLES, but I recommend you look up all of them to give you an idea what your options are.

    Generating the triangles is up to you. If your name is short, generating them by hand should be fairly easy. Note that you should entirely replace the random-point-generating code; options include:

    • with inline data
    • with some code to load the coordinates from a file
    • with something more clever so you don't have to hand-generate them