首页 文章

如何用SDL2和OpenGL绘制三角形?

提问于
浏览
1

我正在使用SD中的SDL2和OpenGL开发一个简单的应用程序 .

问题是我的程序没有绘制三角形 .

Rect.hpp(绘制三角形的类):

#ifndef Rect_hpp
#define Rect_hpp

#include <stdio.h>
#include <iostream>
#define GLEW_STATIC
#include <GL/glew.h>
#include <SDL2/SDL.h>
#include "Shaders.hpp"

using namespace std;

extern GLfloat vertices[];

class Rect
{

public:
 Rect();
 ~Rect();
 void init();
void draw();

private:
 void bind();

 GLuint VAO;
 GLuint VBO;
 GLuint vertexShader;
 GLuint fragmentShader;
 GLuint shaderProgram;
 Shaders shaders;

};

#endif /* Rect_hpp */

Rect.cpp:

#include "Rect.hpp"

GLfloat vertices[] = {
-0.5f, -0.5f, 0.0f,
0.5f, -0.5f, 0.0f,
0.0f, 0.5f, 0.0f,
};

Rect::Rect()
{
VBO = NULL;
vertexShader = NULL;
fragmentShader = NULL;
shaderProgram = NULL;
}

Rect::~Rect()
{
glDeleteShader(vertexShader);
vertexShader = NULL;
glDeleteShader(fragmentShader);
fragmentShader = NULL;
}

void Rect::bind()
{
glBindVertexArray(VAO);

    glBindBuffer(GL_ARRAY_BUFFER, VBO); //VBO activation
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);

    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(GLfloat (GLvoid*)0);
    glEnableVertexAttribArray(0);

glBindVertexArray(0);
}

void Rect::init()
{
//VAO
glGenVertexArrays(1, &VAO); //VAO creation

//VBO
glGenBuffers(1, &VBO); //VBO creation

//SHADER
vertexShader = glCreateShader(GL_VERTEX_SHADER); //vertex shader
glShaderSource(vertexShader, 1, &shaders.vertexSource, NULL);
glCompileShader(vertexShader);

fragmentShader = glCreateShader(GL_FRAGMENT_SHADER); //fragment shader
glShaderSource(fragmentShader, 1, &shaders.fragmentSource, NULL);
glCompileShader(fragmentShader);

shaderProgram = glCreateProgram(); //shader program
glAttachShader(shaderProgram, vertexShader);
glAttachShader(shaderProgram, fragmentShader);
glLinkProgram(shaderProgram);

bind();
}

void Rect::draw()
{
 glUseProgram(shaderProgram);
 glBindVertexArray(VAO);
 glDrawArrays(GL_TRIANGLES, 0, 3);
 glBindVertexArray(0);
}

Game.hpp:

#ifndef Game_hpp
#define Game_hpp

#include <stdio.h>
#include <iostream>
#define GLEW_STATIC
#include <GL/glew.h>
#include <SDL2/SDL.h>
#include <SDL2/SDL_opengl.h>
#include <OpenGL/gl3.h>
#include "glm/glm.hpp"
#include "Rect.hpp"

  using namespace glm;
  using namespace std;

  class Game
{

public:
Game(int width, int height);
~Game();
void run();

private:
int _width, _height;

void init();
void loop();
void input();
void draw();

SDL_Window* window;
SDL_GLContext context;
bool isRunning;
SDL_Event e;
Rect* rect;

};

#endif /* Game_hpp */

Game.cpp:

#include "Game.hpp"

Game::Game(int width, int height)
{
 _width = width;
 _height = height;

window = NULL;
context = NULL;

rect = new Rect();

 isRunning = true;
}

 Game::~Game()
 {
 SDL_GL_DeleteContext(context);
 context = NULL;
 SDL_DestroyWindow(window);
 window = NULL;
 SDL_Quit();
 }

void Game::run()
{
 init();
 loop();
}

void Game::init()
{
 //SDL INIT
 SDL_Init(SDL_INIT_EVERYTHING);

 //OPENGL ATTRIBUTES
 SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK,  SDL_GL_CONTEXT_PROFILE_CORE);
 SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
 SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 3);
 SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24);
 SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 8);

  //WINDOW INIT
  window = SDL_CreateWindow("OpenGL_GAME_TEST",
                          SDL_WINDOWPOS_CENTERED,
                          SDL_WINDOWPOS_CENTERED,
                          _width,
                          _height,
                          SDL_WINDOW_OPENGL | SDL_WINDOW_SHOWN);
glViewport(0, 0, _width, _height);

//OPENGL CONTEXT INIT
context = SDL_GL_CreateContext(window);

//GLEW INIT
glewExperimental = GL_TRUE;
if(glewInit() != GLEW_OK)
    cout << "ERROR: GLEW initialization failed!" << endl;

//CLASSES INIT
rect->init();

}

void Game::loop()
{
while(isRunning)
{
    input();
    draw();
}
}

void Game::input()
{
if(SDL_PollEvent(&e))
{

    if(e.type == SDL_QUIT) isRunning = false;
    if(e.type == SDL_KEYDOWN)
        if(e.key.keysym.sym == SDLK_ESCAPE) isRunning = false;

}
}

void Game::draw()
{
//DRAW...
glClearColor(0.2f, 0.4f, 0.5f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);

rect->draw();

SDL_GL_SwapWindow(window);
}

Shaders.hpp:

#ifndef Shaders_hpp
#define Shaders_hpp

#include <stdio.h>
#include <iostream>
#include <GL/glew.h>

  class Shaders
{

public:
Shaders();
~Shaders();
const GLchar* vertexSource;
const GLchar* fragmentSource;

};

#endif /* Shaders_hpp */

Shaders.cpp:

#include "Shaders.hpp"

Shaders::Shaders()
{
vertexSource = "#version 330 core \n"
               "layout (location = 0) in vec3 position; \n"
               "void main() \n"
               "{ \n"
               "    gl_Position = vec4(position, 1.0); \n"
               "} \n \0";

fragmentSource = "#version 330 core \n"
                 "out vec4 color \n"
                 "void main() \n"
                 "{ \n"
                 "  color = vec4(1.0, 0.5, 0.1, 1.0); \n"
                 "}; \n \0";
 }

Shaders::~Shaders()
{ 

}

2 回答

  • -1

    Minimal runnable example

    编译:

    sudo apt-get install libsdl2-dev
    gcc opengl.c -lSDL2 -lGL -lGLEW
    

    在Ubuntu 16.04上测试过 .

    #include <stdio.h>
    
    #include <SDL2/SDL.h>
    #define GLEW_STATIC
    #include <GL/glew.h>
    
    static const GLuint WIDTH = 512;
    static const GLuint HEIGHT = 512;
    static const GLchar* vertex_shader_source =
        "#version 120\n"
        "attribute vec2 coord2d;\n"
        "void main() {\n"
        "    gl_Position = vec4(coord2d, 0.0, 1.0);\n"
        "}\n";
    static const GLchar* fragment_shader_source =
        "#version 120\n"
        "void main() {\n"
        "    gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);\n"
        "}\n";
    static GLfloat vertices[] = {
         0.0,  0.8,
        -0.8, -0.8,
         0.8, -0.8,
    };
    
    GLuint common_get_shader_program(
        const char *vertex_shader_source,
        const char *fragment_shader_source
    ) {
        GLchar *log = NULL;
        GLint log_length, success;
        GLuint fragment_shader, program, vertex_shader;
    
        /* Vertex shader */
        vertex_shader = glCreateShader(GL_VERTEX_SHADER);
        glShaderSource(vertex_shader, 1, &vertex_shader_source, NULL);
        glCompileShader(vertex_shader);
        glGetShaderiv(vertex_shader, GL_COMPILE_STATUS, &success);
        glGetShaderiv(vertex_shader, GL_INFO_LOG_LENGTH, &log_length);
        log = malloc(log_length);
        if (log_length > 0) {
            glGetShaderInfoLog(vertex_shader, log_length, NULL, log);
            printf("vertex shader log:\n\n%s\n", log);
        }
        if (!success) {
            printf("vertex shader compile error\n");
            exit(EXIT_FAILURE);
        }
    
        /* Fragment shader */
        fragment_shader = glCreateShader(GL_FRAGMENT_SHADER);
        glShaderSource(fragment_shader, 1, &fragment_shader_source, NULL);
        glCompileShader(fragment_shader);
        glGetShaderiv(fragment_shader, GL_COMPILE_STATUS, &success);
        glGetShaderiv(fragment_shader, GL_INFO_LOG_LENGTH, &log_length);
        if (log_length > 0) {
            log = realloc(log, log_length);
            glGetShaderInfoLog(fragment_shader, log_length, NULL, log);
            printf("fragment shader log:\n\n%s\n", log);
        }
        if (!success) {
            printf("fragment shader compile error\n");
            exit(EXIT_FAILURE);
        }
    
        /* Link shaders */
        program = glCreateProgram();
        glAttachShader(program, vertex_shader);
        glAttachShader(program, fragment_shader);
        glLinkProgram(program);
        glGetProgramiv(program, GL_LINK_STATUS, &success);
        glGetProgramiv(program, GL_INFO_LOG_LENGTH, &log_length);
        if (log_length > 0) {
            log = realloc(log, log_length);
            glGetProgramInfoLog(program, log_length, NULL, log);
            printf("shader link log:\n\n%s\n", log);
        }
        if (!success) {
            printf("shader link error");
            exit(EXIT_FAILURE);
        }
    
        /* Cleanup. */
        free(log);
        glDeleteShader(vertex_shader);
        glDeleteShader(fragment_shader);
        return program;
    }
    
    int main(void) {
        GLint attribute_coord2d;
        GLuint program, vbo;
        SDL_Event event;
        SDL_GLContext gl_context;
        SDL_Window *window;
    
        SDL_Init(SDL_INIT_TIMER | SDL_INIT_VIDEO);
        window = SDL_CreateWindow(__FILE__, 0, 0,
                WIDTH, HEIGHT, SDL_WINDOW_OPENGL);
        gl_context = SDL_GL_CreateContext(window);
        glewInit();
    
        /* Shader setup. */
        program = common_get_shader_program(vertex_shader_source, fragment_shader_source);
        attribute_coord2d = glGetAttribLocation(program, "coord2d");
    
        /* Buffer setup. */
        glGenBuffers(1, &vbo);
        glBindBuffer(GL_ARRAY_BUFFER, vbo);
        glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
        glVertexAttribPointer(attribute_coord2d, 2, GL_FLOAT, GL_FALSE, 0, 0);
        glBindBuffer(GL_ARRAY_BUFFER, 0);
    
        /* Global draw state */
        glUseProgram(program);
        glViewport(0, 0, WIDTH, HEIGHT);
        glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
    
        /* Main loop. */
        while (1) {
            glClear(GL_COLOR_BUFFER_BIT);
            glEnableVertexAttribArray(attribute_coord2d);
            glDrawArrays(GL_TRIANGLES, 0, 3);
            glDisableVertexAttribArray(attribute_coord2d);
            SDL_GL_SwapWindow(window);
            if (SDL_PollEvent(&event) && event.type == SDL_QUIT)
                break;
        }
    
        /* Cleanup. */
        glDeleteBuffers(1, &vbo);
        glDeleteProgram(program);
        SDL_GL_DeleteContext(gl_context);
        SDL_DestroyWindow(window);
        SDL_Quit();
        return EXIT_SUCCESS;
    }
    
  • 4

    我解决了,问题在于着色器的写作

相关问题