우분투에서 전체 화면 동작과 관련하여 이상한 점이 있습니다. 창 모드는 정상적으로 작동하지만 "fake"(SDL_WINDOW_FULLSCREEN
) 및 "실제"(SDL_WINDOW_FULLSCREEN_DESKTOP
) 전체 화면 모드는 아닙니다.우분투의 전체 화면 모드 (SDL + OpenGL)
Windows에서 "fake"전체 화면 모드는 비디오 모드를 변경하고 전체 내용이 창에 표시되는 것을 보았습니다. "실제"전체 화면 모드는 데스크톱 크기를 사용합니다. 이 모드에서는 윈도우 왼쪽 상단 모서리에 윈도우 내용을 그리고 여분의 영역을 비워 둡니다.
우분투에서 "가짜"전체 화면 모드는 비디오 모드 변경을 수행하고 창의 내용은 전체 디스플레이로 확장되지만 일부분 만 그려집니다. 상단 부분 (디스플레이의 90 % 이상) 또는 하단 부분 (디스플레이의 10 % 미만) 중 하나입니다. 그려지지 않은 부분은 검은 색이거나 응용 프로그램이 설치되기 전에 화면에 그려진 것을 포함합니다. 때로는 응용 프로그램이 종료시 다시 비디오 모드를 변경하지 않습니다. 하단 부분 만 그려지더라도 커서는 상단 부분 내부에 고정됩니다.
"실제"전체 화면 모드는 완전히 검은 색이거나 디스플레이의 가운데에 창의 내용을 표시합니다. 내용이 상단으로 이동하고 해당 영역 주변의 모든 것이 검은 색입니다 (배경색은 그렇지 않음). 이 모드에서는 커서가 해당 영역 내에서 잠 깁니다.
런타임에서 전체 화면 모드를 변경하면 동작이 조금씩 달라집니다. 즉, 커서가 잠겨있는 영역 인 "그리기 영역"은 "실제"모드의 위/아래뿐만 아니라 "실제" .
- Windows에서 "가짜"전체 화면 모드 :가 (800 × 600 비디오 모드)는
- Windows에서 "진짜"전체 화면 모드 :이 (800 × 600 윈도우의 내용이 구석에 그려, 다른 지역은 빈) 우분투에
- "가짜"전체 화면 모드 : (800 × 600 비디오 모드가 아닌 전체 영역을 볼 수 있습니다 당신은 생각의 gedit의 일부를 볼 수 있습니다..)
- "진짜"전체 화면 우분투 모드 :
내가 수동 해요) (센터 800 × 600 지역 있지만, 이미지가 위로 이동 (빨간색 사각형은 모서리에 될 운명) OpenGL을 사용하여 SDL 대신 화면에 그립니다. 문제를 보여주는 작은 예제를 썼습니다. 800x600 창을 만들고 중심에 파란색 삼각형을 그립니다. 녹색 사각형은 화면 모서리에 그려지고 빨간색 사각형은 창 모서리에 그려집니다 (녹색 사각형은 더 크고 빨간색 사각형은 그 위에 그려집니다). 하나는 각각 '1', '2'또는 '3'키를 사용하여 윈도우화된 "가짜"또는 "실제"전체 화면 모드로 들어갈 수 있습니다. Esc 키를 누르면 응용 프로그램이 닫힙니다.
#include <SDL.h>
#include <GL/gl.h>
#define FULLSCREEN 0
#define WIDTH 800
#define HEIGHT 600
//fullscreen:
// 0 - windowed mode,
// 1 - "fake" fullscreen mode,
// 2 - "real" fullscreen mode
int real_width;
int real_height;
//screen width & height - to draw green square that shows us actual screen size
void set_viewport(SDL_Window* window);
void draw(SDL_Window* window);
int main(int argc, char* argv[]) {
SDL_Init(SDL_INIT_VIDEO);
int position;
#if FULLSCREEN == 0
position = SDL_WINDOWPOS_CENTERED;
#else
position = 0;
#endif
//the only thing I've found - some guy said it works
//if window is in (0,0) while entering fullscreen
//well, it's not, but I've kept it
int flags = SDL_WINDOW_OPENGL;
#if FULLSCREEN == 1
flags |= SDL_WINDOW_FULLSCREEN;
#elif FULLSCREEN == 2
flags |= SDL_WINDOW_FULLSCREEN_DESKTOP;
#endif
SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 5);
SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 5);
SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 5);
SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 16);
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
SDL_Window* window = SDL_CreateWindow(
"",
position, position, /* centered/(0,0) */
WIDTH, HEIGHT, /* request 800x600 window */
flags /* needed mode */
);
//setup GL
SDL_GLContext glcontext = SDL_GL_CreateContext(window);
glShadeModel(GL_SMOOTH);
glCullFace(GL_BACK);
glFrontFace(GL_CCW);
glEnable(GL_CULL_FACE);
//viewport and projection
set_viewport(window);
draw(window);
bool done = false;
while(!done) {
draw(window);
SDL_Event event;
while(SDL_PollEvent(&event)) {
switch(event.type) {
case SDL_QUIT: done = true; break;
case SDL_KEYDOWN:
if(event.key.keysym.scancode == SDL_SCANCODE_ESCAPE)
done = true;
else if(event.key.keysym.scancode == SDL_SCANCODE_1) {
SDL_SetWindowFullscreen(window, 0);
set_viewport(window);
} else if(event.key.keysym.scancode == SDL_SCANCODE_2) {
SDL_SetWindowFullscreen(window, SDL_WINDOW_FULLSCREEN);
set_viewport(window);
} else if(event.key.keysym.scancode == SDL_SCANCODE_3) {
SDL_SetWindowFullscreen(window, SDL_WINDOW_FULLSCREEN_DESKTOP);
set_viewport(window);
}
break;
}
}
}
SDL_GL_DeleteContext(glcontext);
SDL_DestroyWindow(window);
SDL_Quit();
return 0;
}
void set_viewport(SDL_Window* window) {
SDL_GetWindowSize(window, &real_width, &real_height);
glClearColor(1, 1, 1, 1);
glViewport(0, 0, real_width, real_height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0, real_width, real_height, 0, -1, 0);
}
void draw_triangle();
void draw_square(int x, int y, float side);
void draw(SDL_Window* window) {
glClear(GL_COLOR_BUFFER_BIT);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
//triangle on while background
glClearColor(1, 1, 1, 1);
draw_triangle();
//green square at screen corner
glColor3f(0, 1, 0);
draw_square(real_width, real_height, 20);
//red square at window corner
glColor3f(1, 0, 0);
draw_square(WIDTH, HEIGHT, 10);
SDL_GL_SwapWindow(window);
}
void draw_triangle() {
const float w = 460;
const float h = 400;
float colorBuffer[9] = {
0, 0.43f, 0.85f /*#006dd9*/,
0, 0.22f, 0.43f /*#00376e*/,
0, 0.43f, 0.85f /*#006dd9*/
};
float vertexBuffer[9] = {
0, 0, 0,
w/2, h, 0,
w, 0, 0
};
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_COLOR_ARRAY);
glTranslatef((WIDTH-w)/2,(HEIGHT-h)/2,0);
glColorPointer(3, GL_FLOAT, 0, colorBuffer);
glVertexPointer(3, GL_FLOAT, 0, vertexBuffer);
glDrawArrays(GL_TRIANGLE_FAN, 0, 3);
glTranslatef(-(WIDTH-w)/2,-(HEIGHT-h)/2,0);
glDisableClientState(GL_COLOR_ARRAY);
glDisableClientState(GL_VERTEX_ARRAY);
}
void draw_square(int x, int y, float side) {
float vertexBuffer[12] = {
0, 0, 0, /*top left*/
0, side, 0, /*bottom left*/
side, side, 0, /*bottom right*/
side, 0, 0 /*top right*/
};
glEnableClientState(GL_VERTEX_ARRAY);
glTranslatef(x-side/2, y-side/2, 0);
glVertexPointer(3, GL_FLOAT, 0, vertexBuffer);
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
glTranslatef(-x+side/2, -y+side/2, 0);
glDisableClientState(GL_VERTEX_ARRAY);
}
SDL_WINDOW_FULLSCREEN은 "사용자가 요청한 것보다 가장 가까운 일치하는 비디오 모드로 전체 화면으로 이동"을 의미하는 반면 SDL_WINDOW_FULLSCREEN_DESKTOP은 "현재 데스크톱 해상도로 전체 화면으로 이동"을 의미합니다. Linux에서 모드를 변경하면 윈도우 관리자, 그래픽 카드 드라이버, 모니터 수, xrandr 지원 등에 따라 제대로 작동하지 않을 수도 있습니다 (예 : KDE + nVidia blob + Twinview). 시스템이 예상대로 작동하지 않으면 가능한 한 자세하게 버그를 기입하십시오. – gabomdq