OpenGL + SDL 有时会偏离坐标
OpenGL + SDL sometimes draws off from coordinates
我找不到关于类似问题的问题,所以在长时间潜伏在 Whosebug 之后,我决定终于问一个问题。我在 Ubuntu 14.04 LTS 上使用 SDL + OpenGL 时遇到的问题是,有时当我在屏幕上绘制纹理和文本时,坐标有点偏离。我这里有一张图片显示了正确的绘图方式(程序打开全屏但我剪裁了图片)
下面是纹理和文本的绘制有时如何显示
如您所见,此处未显示 fps 文本,鼠标坐标和纹理也太高了。无论如何,当我将鼠标移到左上角时,显示的坐标应该是 0,0。
下面是我用来绘制的代码
#include <SDL2/SDL.h>
#include <SDL2/SDL_image.h>
#include <SDL2/SDL_opengl.h>
#include <GL/gl.h>
#include <GL/glu.h>
#include <GL/glut.h>
#include <sstream>
#include <iostream>
#define WINDOW_WIDTH 1366
#define WINDOW_HEIGHT 768
void drawText(const float x, const float y, const std::string text){
int i;
glColor4f(1.0, 1.0, 1.0, 1.0);
glRasterPos2f(x,y);
glDisable(GL_TEXTURE);
glDisable(GL_TEXTURE_2D);
for(i=0; i<text.length(); ++i){
glutBitmapCharacter(GLUT_BITMAP_9_BY_15, (int)text.at(i));
}
glEnable(GL_TEXTURE_2D);
glEnable(GL_TEXTURE);
}
int main(int argc, char* argv[]){
SDL_Window* window = NULL;
SDL_GLContext context;
SDL_Surface* image = NULL;
SDL_Event event;
GLuint texture;
const Uint8 *keyState;
Uint32 mouseState;
bool run = true;
unsigned long int frameCount = 0;
unsigned long int lastTicks = 0;
unsigned short int fps = 0;
int mouseX = 0;
int mouseY = 0;
std::stringstream buffer;
std::stringstream mouseCoords;
if (SDL_Init(SDL_INIT_EVERYTHING) < 0) {
printf("SDL_Error 1: %s\n", SDL_GetError());
exit(1);
}
glutInit(&argc, NULL);
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
window = SDL_CreateWindow("SDL 2", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, WINDOW_WIDTH, WINDOW_HEIGHT, SDL_WINDOW_FULLSCREEN | SDL_WINDOW_OPENGL);
if (window == NULL) {
printf("SDL_Error 2: %s\n", SDL_GetError());
exit(1);
}
image = SDL_LoadBMP("resources/images/test.bmp");
context = SDL_GL_CreateContext(window);
gluOrtho2D(0.0f, (float)WINDOW_WIDTH, (float)WINDOW_HEIGHT, 0.0f);
glEnable(GL_TEXTURE_2D);
glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_2D, texture);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexImage2D(GL_TEXTURE_2D, 0, image->format->BytesPerPixel, image->w, image->h, 0, GL_RGB, GL_UNSIGNED_BYTE, image->pixels);
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
while(run){
glClear(GL_COLOR_BUFFER_BIT);
glBindTexture(GL_TEXTURE_2D, texture);
glBegin(GL_QUADS);
glTexCoord2f(0.0f, 0.0f);
glVertex2f(10.0f, 50.0f);
glTexCoord2f(1.0f, 0.0f);
glVertex2f(74.0f, 50.0f);
glTexCoord2f(1.0f, 1.0f);
glVertex2f(74.0f, 114.0);
glTexCoord2f(0.0f, 1.0f);
glVertex2f(10.0f, 114.0f);
glEnd();
keyState = SDL_GetKeyboardState(NULL);
mouseState = SDL_GetMouseState(&mouseX, &mouseY);
while(SDL_PollEvent(&event)){
switch(event.type){
case SDL_QUIT:
run = false;
break;
}
}
if(keyState[SDL_SCANCODE_ESCAPE]){
run = false;
}
mouseCoords << "mouseCoords=";
mouseCoords << mouseX;
mouseCoords << ",";
mouseCoords << mouseY;
++frameCount;
if(SDL_GetTicks()-lastTicks >= 1000){
fps = frameCount;
frameCount = 0;
lastTicks = SDL_GetTicks();
}
buffer << "fps=";
buffer << fps;
drawText(10, 20, buffer.str());
drawText(10, 40, mouseCoords.str());
mouseCoords.str("");
buffer.str("");
SDL_GL_SwapWindow(window);
}
glDeleteTextures(1, &texture);
SDL_FreeSurface(image);
SDL_GL_DeleteContext(context);
SDL_DestroyWindow(window);
SDL_Quit();
return 0;
}
似乎通过将标志 SDL_WINDOW_BORDERLESS 添加到 SDL_CreateWindow() 函数调用,问题就消失了。
所以通过修改行
window = SDL_CreateWindow("SDL 2", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, WINDOW_WIDTH, WINDOW_HEIGHT, SDL_WINDOW_FULLSCREEN | SDL_WINDOW_OPENGL);
到这个格式
window = SDL_CreateWindow("SDL 2", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, WINDOW_WIDTH, WINDOW_HEIGHT, SDL_WINDOW_FULLSCREEN | SDL_WINDOW_BORDERLESS | SDL_WINDOW_OPENGL);
这个问题可以解决。
我找不到关于类似问题的问题,所以在长时间潜伏在 Whosebug 之后,我决定终于问一个问题。我在 Ubuntu 14.04 LTS 上使用 SDL + OpenGL 时遇到的问题是,有时当我在屏幕上绘制纹理和文本时,坐标有点偏离。我这里有一张图片显示了正确的绘图方式(程序打开全屏但我剪裁了图片)
下面是纹理和文本的绘制有时如何显示
如您所见,此处未显示 fps 文本,鼠标坐标和纹理也太高了。无论如何,当我将鼠标移到左上角时,显示的坐标应该是 0,0。
下面是我用来绘制的代码
#include <SDL2/SDL.h>
#include <SDL2/SDL_image.h>
#include <SDL2/SDL_opengl.h>
#include <GL/gl.h>
#include <GL/glu.h>
#include <GL/glut.h>
#include <sstream>
#include <iostream>
#define WINDOW_WIDTH 1366
#define WINDOW_HEIGHT 768
void drawText(const float x, const float y, const std::string text){
int i;
glColor4f(1.0, 1.0, 1.0, 1.0);
glRasterPos2f(x,y);
glDisable(GL_TEXTURE);
glDisable(GL_TEXTURE_2D);
for(i=0; i<text.length(); ++i){
glutBitmapCharacter(GLUT_BITMAP_9_BY_15, (int)text.at(i));
}
glEnable(GL_TEXTURE_2D);
glEnable(GL_TEXTURE);
}
int main(int argc, char* argv[]){
SDL_Window* window = NULL;
SDL_GLContext context;
SDL_Surface* image = NULL;
SDL_Event event;
GLuint texture;
const Uint8 *keyState;
Uint32 mouseState;
bool run = true;
unsigned long int frameCount = 0;
unsigned long int lastTicks = 0;
unsigned short int fps = 0;
int mouseX = 0;
int mouseY = 0;
std::stringstream buffer;
std::stringstream mouseCoords;
if (SDL_Init(SDL_INIT_EVERYTHING) < 0) {
printf("SDL_Error 1: %s\n", SDL_GetError());
exit(1);
}
glutInit(&argc, NULL);
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
window = SDL_CreateWindow("SDL 2", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, WINDOW_WIDTH, WINDOW_HEIGHT, SDL_WINDOW_FULLSCREEN | SDL_WINDOW_OPENGL);
if (window == NULL) {
printf("SDL_Error 2: %s\n", SDL_GetError());
exit(1);
}
image = SDL_LoadBMP("resources/images/test.bmp");
context = SDL_GL_CreateContext(window);
gluOrtho2D(0.0f, (float)WINDOW_WIDTH, (float)WINDOW_HEIGHT, 0.0f);
glEnable(GL_TEXTURE_2D);
glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_2D, texture);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexImage2D(GL_TEXTURE_2D, 0, image->format->BytesPerPixel, image->w, image->h, 0, GL_RGB, GL_UNSIGNED_BYTE, image->pixels);
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
while(run){
glClear(GL_COLOR_BUFFER_BIT);
glBindTexture(GL_TEXTURE_2D, texture);
glBegin(GL_QUADS);
glTexCoord2f(0.0f, 0.0f);
glVertex2f(10.0f, 50.0f);
glTexCoord2f(1.0f, 0.0f);
glVertex2f(74.0f, 50.0f);
glTexCoord2f(1.0f, 1.0f);
glVertex2f(74.0f, 114.0);
glTexCoord2f(0.0f, 1.0f);
glVertex2f(10.0f, 114.0f);
glEnd();
keyState = SDL_GetKeyboardState(NULL);
mouseState = SDL_GetMouseState(&mouseX, &mouseY);
while(SDL_PollEvent(&event)){
switch(event.type){
case SDL_QUIT:
run = false;
break;
}
}
if(keyState[SDL_SCANCODE_ESCAPE]){
run = false;
}
mouseCoords << "mouseCoords=";
mouseCoords << mouseX;
mouseCoords << ",";
mouseCoords << mouseY;
++frameCount;
if(SDL_GetTicks()-lastTicks >= 1000){
fps = frameCount;
frameCount = 0;
lastTicks = SDL_GetTicks();
}
buffer << "fps=";
buffer << fps;
drawText(10, 20, buffer.str());
drawText(10, 40, mouseCoords.str());
mouseCoords.str("");
buffer.str("");
SDL_GL_SwapWindow(window);
}
glDeleteTextures(1, &texture);
SDL_FreeSurface(image);
SDL_GL_DeleteContext(context);
SDL_DestroyWindow(window);
SDL_Quit();
return 0;
}
似乎通过将标志 SDL_WINDOW_BORDERLESS 添加到 SDL_CreateWindow() 函数调用,问题就消失了。
所以通过修改行
window = SDL_CreateWindow("SDL 2", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, WINDOW_WIDTH, WINDOW_HEIGHT, SDL_WINDOW_FULLSCREEN | SDL_WINDOW_OPENGL);
到这个格式
window = SDL_CreateWindow("SDL 2", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, WINDOW_WIDTH, WINDOW_HEIGHT, SDL_WINDOW_FULLSCREEN | SDL_WINDOW_BORDERLESS | SDL_WINDOW_OPENGL);
这个问题可以解决。