Search code examples
c++openglsdlnvidiaubuntu-18.04

Using SDL2 and OpenGL to compile a simple triangle


This question has been posed all over the internet yet every code example I try seem to have the same result as all the attempts I have personally pursued towards generating a simple triangle with OpenGL and SDL2. Before switching to a different windowing API my curiosity won't allow me to let this dilemma simply be.

As for my question to be solved, I simply wish to figure out whether the source is my system ( in consideration to the fact that all the code examples I have found all look similar and seems to make itself known on 2 different computers ) or if I'm just doing something wrong myself.

My PC has a GTX 1050m running on ubuntu 18.04 my drivers are the official nvidia drivers on the ubuntu ppa it is capable of OpenGL 4.6

This is display.h my header file for initializing SDL2 and Glew

#ifndef DISPLAY_H
#define DISPLAY_H

#include<SDL2/SDL.h>
#include<string>

class Display
{
public:
    //initializes SDL2 and Glew
    Display( int width, int height, const std::string& title );

    //Clears the screen and creates a triangle
    void Clear();
    //Calls SDL_GL_SwapWindow()
    void Update();
    //Determines whether or not SDL_QUIT Event is called
    bool IsClosed();

    //Destroys application
    virtual ~Display();
protected:
private:
    Display( const Display& other )
    void operator=( const Display& other );

    SDL_Window* m_window;
    SDL_GLContext m_glContext;
    bool m_isClosed;

};
#endif //DISPLAY_H

This is display.cpp

//Constructor and Destructor container 
#include"display.h"
//Glew container
#include<GL/glew.h>
//Standard I\0 lib
#include<cstdio>

//Constructor
Display::Display( int width, int height, const std::string& title )
{
    //SDL2 initialization and error check 
    if( SDL_Init( SDL_INIT_VIDEO ) != 0 ){
    printf( "Unable to initialize SDL: %s\n", SDL_GetError() );
    SDL_ClearError();
    }

    SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8);
    SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8);
    SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8);
    SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 16);
    SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
    SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK,
                        SDL_GL_CONTEXT_PROFILE_COMPATIBILITY );

    //SDL Create window stored in variable m_window
    m_window = SDL_CreateWindow( title.c_str(),
                                 SDL_WINDOWPOS_UNDEFINED,
                                 SDL_WINDOWPOS_UNDEFINED,
                                 width,
                                 height,
                                 SDL_WINDOW_OPENGL|SDL_WINDOW_RESIZABLE );

    // Error checking window
    if( !m_window ) {
    fprintf( stderr, "Could not create window: %s\n", SDL_GetError() );
    return;
    }

    //Creates OpenGL context
    m_glContext = SDL_GL_CreateContext( m_window );
    if ( !m_glContext ){
    fprintf( stderr, "Couldn't create context: %s\n", SDL_GetError() );
    return;
    }

    //Makes the open window the current context
    SDL_GL_MakeCurrent( m_window, m_glContext );

    //Checks How OpenGL handled setting 
    int rs, gs,bs;

    SDL_GL_GetAttribute( SDL_GL_RED_SIZE, &rs );
    SDL_GL_GetAttribute( SDL_GL_GREEN_SIZE, &gs );
    SDL_GL_GetAttribute( SDL_GL_BLUE_SIZE, &bs );
    printf( "Red size: %d, Green size: %d, Blue size: %d\n", rs, gs, bs );


    //To be implemented
    //glewExperimental = GL_TRUE;

    //initialization of glew
    GLenum status = glewInit();
    if(GLEW_OK != status ){
        printf( "GLEW Error: ", glewGetErrorString( status ) );
    }
        printf( "Status: Using GLEW: %s\n", glewGetString( GLEW_VERSION ) );

}

//Destructer
Display::~Display()
{
    //Deletes GL context
    SDL_GL_DeleteContext( m_glContext );

    //Close and destroy the window
    SDL_DestroyWindow( m_window );

    //Clean up
    SDL_Quit();
}

void Display::Clear()
{
    //Clears the screen
    glClear( GL_COLOR_BUFFER_BIT );

    //Creating a triangle
    glBegin( GL_POLYGON );

    glColor3f( 1, 0, 0 );
    glVertex3f( -0.6, -0.75, 0.5 );

    glColor3f( 0, 1, 0 );
    glVertex3f( 0.6, -0.75, 0 );

    glColor3f( 0, 0, 1 );
    glVertex3f( -0, -0.75, 0 );
    glEnd();
    glFlush();
}

//Closes the window on SDL_QUIT event 
bool Display::IsClosed()
{
    return m_isClosed;
}

void Display::Update()
{
    SDL_GL_SwapWindow( m_window );

    SDL_Event e;

    while( SDL_PollEvent( &e ) )
    {
        if( e.type == SDL_QUIT )
        m_isClosed = true;
    }
}

And finally this is my the simple main.cpp

#include<GL/glew.h>
#include<iostream>
#include"display.h"

int main( int argc, char* argv[] )
{
    Display display( 640, 480, "flagShip" );

    while( !display.IsClosed() )
          {
    display.Clear();

    display.Update();
    }

    return 0;
}

Handy Makefile

CC=g++
OBJS= main.cpp
LINKER_FLAGS= -lSDL2 -lGL -lGLEW
COMPILER_FLAGS= -w -pedantic
OBJ_NAME=flagShip

$(OBJ_NAME):main.o display.o
    $(CC) $(COMPILER_FLAGS) -o $(OBJ_NAME) main.o display.o $(LINKER_FLAGS)

main.o:$(OBJS) display.h
    $(CC) $(COMPILER_FLAGS) -c $(OBJS) 

display.o: display.cpp display.h
    $(CC) $(COMPILER_FLAGS) -c display.cpp                                         

Solution

  • You do not use any view matrix or projection matrix. This means you have to set up the vertex coordinates of the triangle in clip space, respectively in normalized device space.

    The normalized device space is a cube where the left, lower, near coordinate is (-1, -1, -1) and the right, upper, far coordinate is (1, 1, 1):

    NDC

    The projection of the x-axis to the viewport, points from the left to the right and the projection of the y-axis points from the bottom to the top.
    Since all the y-coordinates of your triangle are equal, the triangle is perpendicular to the viewport:

    glVertex3f( -0.6, -0.75, 0.5 );
    ...
    glVertex3f(  0.6, -0.75, 0 );
    ...
    glVertex3f(   -0, -0.75, 0 );   
    

    Swap the y- and z-component of the vertex coordinates of the triangle, to solve the issue:

    glVertex3f( -0.6, 0.5, -0.75 );
    ...
    glVertex3f(  0.6, 0.0, -0.75 );
    ...
    glVertex3f( -0.0, 0.0, -0.75 ); 
    

    Preview:

    preview