简体   繁体   English

使用SDL2和OpenGL编译一个简单的三角形

[英]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. 这个问题已经遍及整个互联网,但是我尝试的每个代码示例似乎都具有与我个人为使用OpenGL和SDL2生成一个简单三角形所做的所有尝试相同的结果。 Before switching to a different windowing API my curiosity won't allow me to let this dilemma simply be. 在切换到其他窗口API之前,我的好奇心不允许我简单地解决这个难题。

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 我的电脑在ubuntu 18.04上运行了GTX 1050m,我的驱动程序是ubuntu ppa上的官方nvidia驱动程序,它能够支持OpenGL 4.6

This is display.h my header file for initializing SDL2 and Glew 这是display.h我的头文件,用于初始化SDL2和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 这是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 最后这是我简单的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 方便的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                                         

Take a piece of graph paper, then draw out the vertex coordinates of your "triangle". 拿一张方格纸,然后画出“三角形”的顶点坐标。 Do you notice something? 你有注意到吗?

  • Hint 1: the area of the triangle you draw is zero. 提示1:绘制的三角形的面积为零。

  • Hint 2: Look at the y-value of the last glVertex call. 提示2:查看最后一次glVertex调用的y值。

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): 规范化的设备空间是一个立方体,其中左,下,近坐标为(-1,-1,-1),右,上,远坐标为(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. x轴到视口的投影从左到右指向,y轴的投影从下到上指向。
Since all the y-coordinates of your triangle are equal, the triangle is perpendicular to the viewport: 由于三角形的所有y坐标都相等,因此三角形垂直于视口:

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: 交换三角形顶点坐标的y和z分量,以解决此问题:

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

Preview: 预习:

预习

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM