SDL2抗锯齿

8

如何在使用SDL_RenderCopyEx时开启抗锯齿?

我发现一些文章建议使用以下方法:

SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 1);
SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, 2);

and

glEnable(GL_MULTISAMPLE);

但这没有任何效果。有什么想法吗?
int Buffers, Samples;
SDL_GL_GetAttribute( SDL_GL_MULTISAMPLEBUFFERS, &Buffers );
SDL_GL_GetAttribute( SDL_GL_MULTISAMPLESAMPLES, &Samples );
cout << "buf = " << Buffers << ", samples = " << Samples;

返回值

buf = -858993460,samples = -858993460。

编辑:代码:

   #include <windows.h>
#include <iostream>

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

using namespace std;


int main( int argc, char * args[] )
{
    // Inicjacja SDL'a
    SDL_Init(SDL_INIT_EVERYTHING);

    SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 1);
    SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, 8);

    SDL_GL_SetAttribute(SDL_GL_ACCELERATED_VISUAL, 1); 

    // Tworzenie okna
    SDL_Window *win = nullptr;
    win = SDL_CreateWindow("abc", 100, 100, 800, 600, SDL_WINDOW_FULLSCREEN | SDL_WINDOW_OPENGL | SDL_WINDOW_SHOWN);

    if (win == nullptr) 
    {
        std::cout << SDL_GetError() << std::endl;
        system("pause");
        return 1;
    }


    int Buffers, Samples;
    SDL_GL_GetAttribute( SDL_GL_MULTISAMPLEBUFFERS, &Buffers );
    SDL_GL_GetAttribute( SDL_GL_MULTISAMPLESAMPLES, &Samples );
    cout << "buf = " << Buffers << ", samples = " << Samples << ".";

    // Create Renderer
    SDL_Renderer *ren = nullptr;
    ren = SDL_CreateRenderer(win, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);

    if (ren == nullptr)
    {
        std::cout << SDL_GetError() << std::endl;
        return 1;
    }

    // Create texture
    SDL_Texture *tex = nullptr;
    tex = IMG_LoadTexture(ren, "circle.png");

    SDL_SetTextureAlphaMod(tex, 100);

    SDL_Rect s,d;
    SDL_Point c;
    s.x = s.y = 0;
    s.w = s.h = 110;

    d.x = 320;
    d.y = 240;
    d.w = d.h = 110;

    c.x = c.y = 55;

    // Event Queue
    SDL_Event e;
    bool quit = false;
    int angle = 0;

    while(!quit)
    {
        while (SDL_PollEvent(&e)){
            //If user closes he window
            if (e.type == SDL_KEYDOWN)
                quit = true;
        }
        angle += 2;

        float a = (angle/255.0)/M_PI*180.0;

        // Render
        SDL_RenderClear(ren);
        SDL_RenderCopyEx(ren, tex, &s, &d, a, &c, SDL_FLIP_NONE);
        SDL_RenderPresent(ren);


    }

    // Release
    SDL_DestroyTexture(tex);
    SDL_DestroyRenderer(ren);
    SDL_DestroyWindow(win);

    // Quit
    SDL_Quit();

    return 0;
}

不用担心与内存释放相关的样式或错误等问题。这只是一个快速的草图,用于测试SDL'a的可能性。


1
你在调用 get attribute 之前创建了上下文吗?你报告的值看起来也像是报告了一个未初始化的变量。 - GMasucci
在我看过的每篇文章/帖子中,都是在SDL Init之后直接进行设置,例如http://stackoverflow.com/questions/4683094/sdl-opengl-multisampling-not-working?rq=1 - l00k
2个回答

15

2
这是一个非常老的问题 :) 我甚至不记得当时在做什么 :) 但是感谢您的时间。我相信这个解决方案是可行的。 - l00k

0
据我试验,只有在创建上下文后才会设置值,因此如果在创建窗口之前运行SDL_GL_GetAttribute代码行,则会返回未初始化的值,就像您目前所做的那样。
因此,在创建上下文后使用SDL_GL_GetAttribute调用以获取正确的值,应该可以正常工作。
让我知道你的进展如何,如果需要更多帮助/信息,我会尽力提供帮助。
补充说明:
看起来你已经在设置窗口属性之前创建了窗口,我粘贴了一些修改过的代码,应该可以正常运行(抱歉,我无法测试它,直到我能够访问我的家用电脑)。
重新排列的代码:
#include <windows.h>
#include <iostream>

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

#include <gl/include/glew.h>

using namespace std;

void myInit()
{
    // SDL Init
    SDL_Init(SDL_INIT_EVERYTHING);

    // Settings
    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_ALPHA_SIZE, 8);

    SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 32);

    SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 1);
    SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, 2);

    SDL_GL_SetAttribute(SDL_GL_ACCELERATED_VISUAL, 1); 

    glEnable(GL_MULTISAMPLE);
}

int main( int argc, char * args[] )
{
    myInit();   

    // Window Create
    SDL_Window *win = nullptr;
    win = SDL_CreateWindow("abc", 100, 100, 800, 600, SDL_WINDOW_SHOWN);

    if(win == nullptr) return 1;

    // Create Renderer
    SDL_Renderer *ren = nullptr;
    ren = SDL_CreateRenderer(win, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);

    if (ren == nullptr) return 1;

    int Buffers, Samples;
    SDL_GL_GetAttribute( SDL_GL_MULTISAMPLEBUFFERS, &Buffers );
    SDL_GL_GetAttribute( SDL_GL_MULTISAMPLESAMPLES, &Samples );
    cout << "buf = " << Buffers << ", samples = " << Samples << ".";

    // Create texture
    SDL_Texture *tex = nullptr;
    tex = IMG_LoadTexture(ren, "circle.png");

    SDL_SetTextureAlphaMod(tex, 100);
    SDL_SetTextureColorMod(tex, 255,0,0);

    SDL_Rect s,d;
    SDL_Point c;
    s.x = s.y = 0;
    s.w = s.h = 110;

    d.x = 320;
    d.y = 240;
    d.w = d.h = 220;

    c.x = c.y = 110;

    // Event Queue
    SDL_Event e;
    bool quit = false;
    int angle = 45.0*M_PI/180;

    while(!quit)
    {
        while (SDL_PollEvent(&e)){
            //If user closes the window
            if (e.type == SDL_QUIT)
                quit = true;
        }

        // Render
        SDL_RenderClear(ren);
        SDL_RenderCopyEx(ren, tex, &s, &d, angle, &c, SDL_FLIP_NONE);
        SDL_RenderPresent(ren);
    }

    // Release
    SDL_DestroyTexture(tex);
    SDL_DestroyRenderer(ren);
    SDL_DestroyWindow(win);

    // Quit
    SDL_Quit();

    return 0;
}

创建窗口和渲染器后,结果相同-没有任何改变。 - l00k
你能否贴一些代码?这样可能会更容易追踪问题。 - GMasucci
抱歉,已删除。我现在显得有些老了,很快就回家了,可以好好测试代码。 - GMasucci
1
如果在渲染上下文创建之后调用glEnable(GL_MULTISAMPLE),那肯定会有所帮助。否则,这只会生成一个GL_INVALID_OPERATION错误。 - Andon M. Coleman
1
我已经在gcc和ms vs 2010和2012中尝试了这段代码,无论我如何更改代码,都会得到相同的结果。我将花费一些时间尝试更多的变化,看看是否可以解决问题。 - GMasucci
显示剩余6条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接