获取SDL2中鼠标位置的纹理坐标?

时间:2019-06-08 22:32:58

标签: c sdl-2

我有一个严格的要求,那就是始终具有512x512分辨率(比如说)的纹理(即使窗口更大,并且SDL在渲染时基本上为我缩放纹理)。这是因为它是经典旧计算机的仿真器,假定纹理固定,因此我无法重写代码以动态采用多种纹理大小和/或纹理比率。

出于上述目的,我使用SDL_RenderSetLogicalSize()

当然,当将其渲染到窗口中时,我可以获得鼠标坐标(相对于窗口),并且可以通过获得真实的窗口大小来“缩放”到纹理位置(因为可以调整窗口的大小)。

但是,这里有一个大问题。一旦窗口的宽高比与纹理的比例不同(例如在全屏模式下,由于现代显示器的比例与我要使用的比例不匹配),在侧面或顶部/底部。很好,因为我希望始终保持相同的纹理比率,并且SDL可以为我做这件事,等等。但是,我找不到一种方法可以根据我强制使用的固定比率来询问SDL我的纹理在窗口内的位置是否完全渲染。因为我只需要纹理中的位置,并且确切的纹理原点是由SDL本身而不是我放置的。

当然,我可以编写一些代码来找出那些“黑条”将如何改变纹理的原点,但是我希望有一种更简单,更优雅的方式来“询问” SDL,因为肯定可以拥有将我的纹理放置在某处的代码,因此我可以重复使用该信息。

我的丑陋(可以优化,我可以避免浮点数学运算,但是作为第一次尝试...)解决方案:

static void get_mouse_texture_coords ( int x, int y )
{
    int win_x_size, win_y_size;
    SDL_GetWindowSize(sdl_win, &win_x_size, &win_y_size);
    // I don't know if there is more sane way for this ...
    // But we must figure out where is the texture within the window,
    // which can be changed since the fixed ratio versus the window ratio (especially in full screen mode)
    double aspect_tex = (double)SCREEN_W / (double)SCREEN_H;
    double aspect_win = (double)win_x_size / (double)win_y_size;
    if (aspect_win >= aspect_tex) {
            // side ratio correction bars must be taken account
            double zoom_factor = (double)win_y_size / (double)SCREEN_H;
            int bar_size = win_x_size - (int)((double)SCREEN_W * zoom_factor);
            mouse_x = (x - bar_size / 2) / zoom_factor;
            mouse_y = y / zoom_factor;
    } else {
            // top-bottom ratio correction bars must be taken account
            double zoom_factor = (double)win_x_size / (double)SCREEN_W;
            int bar_size = win_y_size - (int)((double)SCREEN_H * zoom_factor);
            mouse_x = x / zoom_factor;
            mouse_y = (y - bar_size / 2) / zoom_factor;
    }
}

SCREEN_WSCREEN_H的位置是我的纹理的尺寸,虽然名称易误导,但无论如何。输入参数xy是相对于窗口的鼠标位置(由SDL报告)。 mouse_xmouse_y是结果,即基于纹理的坐标。这似乎很好。但是,有没有理智的解决方案或更好的解决方案?

调用上面函数的代码在我的事件处理程序循环中(当然,我会定期调用它),如下所示:

void handle_sdl_events ( void ) {
    SDL_Event event;
    while (SDL_PollEvent(&event)) {
    switch (event.type) {
        case SDL_MOUSEMOTION:
            get_mouse_texture_coords(event.motion.x, event.motion.y);
            break;
        [...]

0 个答案:

没有答案