2012-02-04 30 views
6

Từ mã tôi có chương trình vẽ và di chuyển hình vuông xung quanh cửa sổ ứng dụng, tôi gặp sự cố khi thay đổi kích thước cửa sổ ứng dụng. Khi tôi xử lý một thay đổi kích thước và thay đổi các tiểu bang cho phù hợp, tất cả mọi thứ trên màn hình cần được rút ra và trước khi thay đổi kích thước biến mất. Tôi không biết tại sao vì không có tọa độ bên trong đối tượng nào được thay đổi trong khi thay đổi kích thước cửa sổ.Xử lý thay đổi kích thước cửa sổ bằng OpenGL và SDL

Câu hỏi của tôi là bất cứ ai có thể chỉ cho tôi đi đúng hướng để giải quyết vấn đề của tôi (mã biên dịch tốt)

void ResizeWindow() 
{ 
    screen_width = event.resize.w; 
    screen_height = event.resize.h; 

    SDL_SetVideoMode(screen_width, screen_height, bpp, SDL_OPENGL | SDL_RESIZABLE | SDL_DOUBLEBUF); 

    glViewport(0, 0, screen_width, screen_height); 
    glMatrixMode(GL_PROJECTION); 
    glOrtho(0, screen_width, 0, screen_height, -1, 1); 
    glLoadIdentity(); 
    glMatrixMode(GL_MODELVIEW); 
    glLoadIdentity(); 
    glClear(GL_COLOR_BUFFER_BIT); 
    glLoadIdentity(); 
} 

vòng lặp chính:.

while (running == true) 

{ 

    while(SDL_PollEvent(&event)) 

    { 

     switch(event.type) 

     { 

      case SDL_VIDEORESIZE: ResizeWindow(); break; // resizing called here 
      case SDL_QUIT: running = false; break; 
      case SDL_KEYDOWN: square.Handle_Input(down); break; 
      case SDL_KEYUP: square.Handle_Input(up); break; 

     } 

    } 

    square.Move(); 
    square.Check_Collision(); 

    glClear(GL_COLOR_BUFFER_BIT); 

    square.Draw(); 

    SDL_GL_SwapBuffers(); 

} 

Tất cả đều chạy một cách hoàn hảo cho đến khi cửa sổ được thay đổi kích cỡ.

+0

Tôi đã xem câu hỏi trước đó của bạn, nhưng không thể xoay quanh để chỉ ra tất cả các vấn đề tại thời điểm đó. Tôi tin rằng bạn không giải quyết được các vấn đề trước đó của bạn. Bạn có lẽ nên đăng các thay đổi bạn đã thực hiện để làm cho nó hoạt động như câu trả lời của riêng bạn và đóng câu hỏi. – batbrat

+0

Đề xuất của tôi có khắc phục được sự cố không? – batbrat

+0

Tôi đã ngủ kể từ khi tôi đăng câu hỏi này, câu trả lời của bạn có ý nghĩa, đặc biệt là bit về SDL_SetVideoMode, nhìn lại nó, nó có vẻ như một sai lầm ngớ ngẩn về phía tôi. Câu hỏi trước tôi đăng tải thực sự có một vấn đề, đó là một sai lầm lớn của tôi; Tôi đã làm việc từ bộ nhớ và không tìm kiếm các thông số glOrtho. Tôi đã có nó như đi từ trái sang phải như 0-0. Tôi sẽ cố gắng đề xuất của bạn ngay bây giờ –

Trả lời

13

Tôi đã sao chép đã dán mã của bạn và tôi sẽ giải thích những gì đang diễn ra theo từng dòng. Nó sẽ giúp bạn nhìn thấy không chỉ lý do tại sao màn hình sẽ trống sau khi thay đổi kích thước, nhưng cũng giúp bạn loại bỏ những thứ mà bạn không thực sự cần.

void ResizeWindow() 
{ 

Những dòng tiếp theo là tốt! Bạn đã nhận được chiều rộng và chiều cao màn hình mới từ sự kiện thay đổi kích thước. Tôi giả định rằng sự kiện có thể truy cập tại thời điểm này trong mã của bạn.

screen_width = event.resize.w; 
    screen_height = event.resize.h; 

Tôi nghi ngờ bạn cần cuộc gọi này đến SDL_SetViedoMode. Tôi hy vọng nó sẽ được sử dụng chỉ trong khi thiết lập cửa sổ OpenGL. Tôi không có kinh nghiệm với việc sử dụng SDL hiện tại, vì vậy tôi không thể chắc chắn. Tôi đã làm một cái nhìn nhanh chóng của tài liệu và dường như hỗ trợ bằng cách sử dụng nó theo cách tôi mong đợi.

SDL_SetVideoMode(screen_width, screen_height, bpp, SDL_OPENGL | SDL_RESIZABLE | SDL_DOUBLEBUF); 

Bây giờ, chúng tôi có được công cụ thú vị GL. Bạn đã đổi kích thước chế độ xem, điều cần thiết.

glViewport(0, 0, screen_width, screen_height); 

Bây giờ, bạn đang tạo ma trận chiếu mới để duy trì khẩu phần (trừ khi tôi nhầm). Bạn đã chuyển sang chế độ ma trận và thiết lập ma trận chiếu chính xác, điều này là hợp lý.

glMatrixMode(GL_PROJECTION); 
    glOrtho(0, screen_width, 0, screen_height, -1, 1); 

Bây giờ, bạn đặt ma trận chiếu thành nhận dạng, ghi đè ma trận chiếu OpenGL cũ và hoàn tác tất cả công việc bạn đã làm. Đây là lý do màn hình trống.

glLoadIdentity(); 

Bây giờ, bạn chuyển sang ma trận chế độ xem mô hình và đặt thành nhận dạng, điều này không thực sự cần thiết, miễn là bạn đang đặt chính xác ở nơi khác.

glMatrixMode(GL_MODELVIEW); 
    glLoadIdentity(); 

Tôi nghi ngờ bạn thực sự cần dòng tiếp theo này. Tại sao bạn muốn xóa màn hình sau khi thay đổi kích thước? Bạn muốn vẽ lại nó, nhưng tôi chắc chắn rằng chức năng vẽ của bạn sẽ xóa màn hình và vẽ đối tượng sẽ được gọi tự động sau khi làm mới xong.

glClear(GL_COLOR_BUFFER_BIT); 

Và bạn chắc chắn không cần phải đặt lại ma trận chế độ xem mô hình hiện tại thành nhận dạng lần thứ hai. OpenGL vẫn đang ở chế độ xem mô hình và ma trận đó đã được đặt thành nhận dạng! Hãy nhớ rằng OpenGL là một máy nhà nước!

glLoadIdentity(); 
} 
1

Một vấn đề bạn có thể có được, mà thay đổi kích thước một cửa sổ với SDL một bối cảnh OpenGL mới được tạo ra, có nghĩa là tất cả những gì bạn đã tải lên trước (kết cấu, các đối tượng đỉnh đệm) và tiểu bang bạn thiết lập (như đỉnh các con trỏ mảng) bị mất. Bạn cần phải khởi tạo lại chúng nếu sử dụng SDL. Nếu bạn muốn giữ chúng, đừng sử dụng SDL để quản lý cửa sổ. Tôi khuyên bạn nên GLFW.

này

void ResizeWindow() 

{ 

screen_width = event.resize.w; 
screen_height = event.resize.h; 

SDL_SetVideoMode(screen_width, screen_height, bpp, SDL_OPENGL | SDL_RESIZABLE | SDL_DOUBLEBUF); 

glViewport(0, 0, screen_width, screen_height); 
glMatrixMode(GL_PROJECTION); 
glOrtho(0, screen_width, 0, screen_height, -1, 1); 
glLoadIdentity(); 
glMatrixMode(GL_MODELVIEW); 
glLoadIdentity(); 
glClear(GL_COLOR_BUFFER_BIT); 
glLoadIdentity(); 

} 

là chống mô hình phổ biến nhất được tìm thấy trong mã của người mới bắt đầu OpenGL. Lệnh vẽ và quản lý trạng thái ảnh hưởng đến bản vẽ thuộc về chức năng vẽ. Đó là như sau:

glViewport(0, 0, screen_width, screen_height); 
glMatrixMode(GL_PROJECTION); 
glOrtho(0, screen_width, 0, screen_height, -1, 1); 
glLoadIdentity(); 
glMatrixMode(GL_MODELVIEW); 
glLoadIdentity(); 
glClear(GL_COLOR_BUFFER_BIT); 
glLoadIdentity(); 

Nếu bạn muốn chương trình OpenGL mạnh mẽ không bao giờ đưa chúng (chỉ) vào trình xử lý thay đổi kích thước. Chúng thuộc về các lệnh vẽ khác.

+0

Tôi nghĩ rằng tôi thấy những gì bạn đang nói. Có thực sự không có nỗ lực tối thiểu để giữ cho chương trình chạy bình thường khi thay đổi kích thước trong SDL? –

+0

Vì vậy, anh ấy cần cuộc gọi đến SDL_SetVideoMode? Trên một lưu ý riêng biệt, không phải là nó hợp lý để thay đổi kích thước khung nhìn và thiết lập các chiếu cả lúc bắt đầu và trong quá trình thay đổi kích cỡ? Trong thực tế, nếu tôi muốn bảo tồn tỷ lệ khung hình, tôi nghĩ rằng đó là điều cần thiết. Đối với ma trận modelview, tôi đã đặt nó trong khi vẽ khi cần thiết. Tất nhiên, điều này không tính đến các thực tiễn OpenGL hiện đại và chỉ xem xét chế độ ngay lập tức. – batbrat

+0

Tôi đồng ý rằng các lệnh vẽ và quản lý trạng thái phải nằm trong chức năng vẽ. Tuy nhiên, tôi thấy thuận tiện khi có ma trận chiếu và khung nhìn được đặt trong hàm thay đổi kích thước (và hàm khởi tạo) khi thực hiện các công cụ đơn giản. – batbrat

Các vấn đề liên quan