调用glGenFramebuffers()时的Segfault?

时间:2017-10-23 16:09:26

标签: c++ opengl sdl glew

我想在3D上做一些2D,所以我可以做一个像样的GUI。所以我创建了纹理等等。

我可以编译代码,它不会产生任何错误。但是当我运行该程序时,一直都是正确的,直到我称之为:

glGenFramebuffers(1, &fb);

然后出现:

error 139 segmentation fault (core dumped).

有人知道代码有什么问题吗?

std::cout << "test1" << std::endl;

unsigned int fb;
glGenFramebuffers(1, &fb);
std::cout << "test2" << std::endl;
glBindRenderbuffer(GL_RENDERBUFFER, fb);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, renderTexture.getId(), 0);

显示“test1”文本,但“test2”不显示。

CODE:

game.cpp

#include "game.h"

game::game(){
    SDL_Init(SDL_INIT_EVERYTHING);
    SDL_Surface* screen = SDL_SetVideoMode(1000, 600, 32, SDL_SWSURFACE|SDL_OPENGL);

    glClearColor(0.5, 0.5, 0.5, 1.0);
    glMatrixMode(GL_PROJECTION);

    glLoadIdentity();
    gluPerspective(45, 1000.0/600.0, 1.0, 500.0);
    glMatrixMode(GL_MODELVIEW);
    glEnable(GL_DEPTH_TEST);
    glEnable(GL_TEXTURE_2D);
}

game::~game(){
    SDL_Quit();
}

void game::start(){
    Uint32 start;
    SDL_Event event;

    texture renderTexture = texture();
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 1000, 600, 0, GL_BGRA, GL_UNSIGNED_BYTE, 0);

    std::cerr << "test1" << std::endl;

    unsigned int fb;
    glGenFramebuffers(1, &fb);
    std::cerr << "test2" << std::endl;
    glBindRenderbuffer(GL_RENDERBUFFER, fb);
    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, renderTexture.getId(), 0);

    bool running = true;
    while (running){
        start = SDL_GetTicks();

        while (SDL_PollEvent(&event)){
            switch (event.type){
                case SDL_QUIT:
                    running = false;
                    break;
            }
        }

        update();
        show(fb);
        showMenu();

        SDL_GL_SwapBuffers();
        if (1000/30 > (SDL_GetTicks()-start)){
            SDL_Delay(1000/30 - (SDL_GetTicks()-start));
        }
    }
}

void game::update(){

}

void game::show(unsigned int fb){

    glBindFramebuffer(GL_FRAMEBUFFER, fb);

    glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
    glLoadIdentity();
}

void game::showMenu(){
    bindWindowAsRenderTarget();

    glViewport(0, 0, 1000, 600);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glOrtho(0.0, 1000.0, 0.0, 600.0, -1.0, 1.0);
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
}

void game::bindWindowAsRenderTarget(){
    glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
    glViewport(0, 0, 1000, 600);
}

game.h

#ifndef GAME_H_INCLUDED
#define GAME_H_INCLUDED

#include <iostream>

#include <SDL/SDL.h>

#include <GL/glew.h>

#include <GL/gl.h>
#include <GL/glu.h>

#include "texture.h"

class game{
    void update();
    void show(unsigned int fb);
    void showMenu();

    void bindWindowAsRenderTarget();

    public:
        game();
        ~game();

        void start();
};

#endif // GAME_H_INCLUDED

的main.cpp

#include "game.h"

int main(int argc, char** argv){
    game g;
    g.start();

    return 0;
}

texture.cpp

#ifndef TEXTURE_H_INCLUDED
#define TEXTURE_H_INCLUDED

#include <SDL/SDL.h>

#include <GL/glew.h>

#include <GL/gl.h>
#include <GL/glu.h>

class texture{
    unsigned int id;

    public:
        texture();
        ~texture();

        void loadImage(const char* filename);
        unsigned int getId();
};

#endif // TEXTURE_H_INCLUDED

texture.cpp

#include "texture.h"

texture::texture(){
    glGenTextures(1, &id);
    glBindTexture(GL_TEXTURE_2D, id);
}

texture::~texture(){
    glDeleteTextures(1, &id);
}

void texture::loadImage(const char* filename){
    SDL_Surface* img = SDL_LoadBMP(filename);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, img->w, img->h, 0, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, img->pixels);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    SDL_FreeSurface(img);
}

unsigned int texture::getId(){
    return id;
}

1 个答案:

答案 0 :(得分:1)

Dollars to donuts#include GL extension loader (GLEW, GLAD, etc.)然后:

  • 在拥有当前GL上下文(保留glGenFramebuffers() NULL之类的函数指针)或
  • 之前尝试初始化它
  • 忘记完全初始化,或
  • (不太可能,除非你做的事情就像试图通过远程桌面使用OpenGL一样)正确地启动你的扩展加载器但是使用不支持核心FBO的GL实现

编辑哦,嘿,这是#2。

您需要在SDL_SetVideoMode()之后致电glewInit()。您还应该使用GLEW版本检查功能来验证底层GL实现的版本是否支持核心FBO(它们是在OpenGL 2.1 IIRC中进行的)。