Текстура рендеринга SDL2 заметно отстает от мыши

Я использую SDL2 в Windows (я тестировал Windows 7 и Windows 8). Я играл с рендерингом текстуры, привязанной к координатам мыши, чтобы создать своего рода эффект «перекрестия».

Это работает, но текстура заметно отстает от мыши, что создает неудобную задержку между движением мыши и отображаемыми обновлениями. Честно говоря, задержка очень незначительна, но для того, кто заботится об абсолютной точности, она сведет с ума.

Мой вопрос в основном, это нормально? Я предполагаю, что задержка связана со временем, которое требуется Windows для доставки события в SDL, а затем SDL для доставки события мне. Как можно добиться эффекта заблокированного «перекрестия» с помощью SDL?

Мой код для справки:

#include "SDL.h"

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

    SDL_Window* window = SDL_CreateWindow("SDL", 100, 100, 640, 480, SDL_WINDOW_SHOWN);

    SDL_Renderer* renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED);

    SDL_Surface* surface = SDL_LoadBMP("mouse.bmp");

    SDL_Texture* texture = SDL_CreateTextureFromSurface(renderer, surface);
    SDL_FreeSurface(surface);

    bool isExiting = false;
    int x = 0;
    int y = 0;

    while(!isExiting)
    {
        SDL_Event e;
        while(SDL_PollEvent(&e))
        {
            if(e.type == SDL_QUIT)
            {
                isExiting = true;
                break;
            }
            else if(e.type == SDL_MOUSEMOTION)
            {
                x = e.motion.x;
                y = e.motion.y;
            }
        }

        SDL_Rect destRect;
        destRect.h = 19;
        destRect.w = 19;
        destRect.x = x;
        destRect.y = y;

        SDL_RenderClear(renderer);
        SDL_RenderCopy(renderer, texture, NULL, &destRect);
        SDL_RenderPresent(renderer);
    }

    SDL_Quit(); 

    return 0; 
}

person Justin Skiles    schedule 04.09.2013    source источник
comment
У вас включен композитор Windows? Ваш основной цикл while всегда занимает ~ 16-17 мс для выполнения?   -  person genpfault    schedule 04.09.2013
comment
@genpfault Составление включено. Буду тестировать при отключении. Я еще не засекал цикл, так что мне придется попробовать и это.   -  person Justin Skiles    schedule 04.09.2013
comment
Ваш SDL_Surface не будет отрисовываться по центру позиции мыши, измените на destRect.x = x - ( destRect.w / 2); destRect.y = y - ( destRect.h / 2);   -  person olevegard    schedule 05.09.2013
comment
@olevegard Я ценю ответ, но проблема не в этом. Существует видимая задержка между движением мыши и рендерингом. Регулировка положения не влияет на эту задержку.   -  person Justin Skiles    schedule 05.09.2013
comment
@JustinSkyles Да, я знаю. Я просто заметил это, поэтому я хотел бы указать на это.   -  person olevegard    schedule 05.09.2013
comment
Ой, это немного более сложная ситуация. Вам нужно использовать V-Sync, чтобы получить это, и для этого вам понадобится многопоточность. В любом случае, функции времени в SDL — это заноза в заднице.   -  person pampeho    schedule 05.09.2013
comment
@Zupoman SDL2 позволяет мне создать средство визуализации с флагом SDL_RENDERER_PRESENTVSYNC, но, похоже, это не имеет значения.   -  person Justin Skiles    schedule 05.09.2013
comment
Попробуйте добавить SDL_Delay() для дросселирования основного цикла. Если вы загружаете ЦП, планировщик переключает вашу программу на более низкий приоритет.   -  person Quentin    schedule 09.06.2015


Ответы (2)


Хотя я не могу быть уверен, почему ваш цикл отстает, SDL поддерживает изменение поверхности мыши, а также некоторые другие функции, которые могут вас заинтересовать. Похоже, вы могли бы найти хорошее применение SDL_CreateColorCursor(SDL_Surface* surface, int hot_x, int hot_y). Вот ссылка на вики-страницу о поддержке мыши: http://wiki.libsdl.org/CategoryMouse

Удачного кодирования!

person BrainSteel    schedule 28.09.2013

В проекте, над которым я работаю, я делаю что-то вроде этого:

(Вне основного игрового цикла):

SDL_Texture* cursor = //blah;
SDL_Rect cursor_hitbox;
SDL_QueryTexture(cursor, NULL, NULL, &cursor_hitbox.w, &cursor_hitbox.h);

(В основном игровом цикле):

SDL_GetMouseState(&cursor_hitbox.x, &cursor_hitbox.y);

При использовании этого я действительно не заметил никакой задержки ввода. Может быть, это просто тип события?

Обратите внимание, что это, скорее всего, не так эффективно, поскольку вы будете получать состояние мыши каждый кадр, а не только при перемещении мыши.

person HelpMe000    schedule 08.06.2015