PNG изображение размыто при загрузке на текстуру - PullRequest
4 голосов
/ 27 апреля 2010

Я создал изображение png в фотошопе с прозрачными пленками, которые я загрузил, и программой OpenGL. Я связал его с текстурой, и в программе картинка выглядит размытой, и я не знаю, почему.

альтернативный текст http://img685.imageshack.us/img685/9130/upload2.png

альтернативный текст http://img695.imageshack.us/img695/2424/upload1e.png

Код загрузки

// Texture loading object
nv::Image title;

// Return true on success
if(title.loadImageFromFile("test.png"))
{
    glGenTextures(1, &titleTex);
    glBindTexture(GL_TEXTURE_2D, titleTex);
    glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_TRUE);
    glTexImage2D(GL_TEXTURE_2D, 0, title.getInternalFormat(), title.getWidth(), title.getHeight(), 0, title.getFormat(), title.getType(), title.getLevel(0));
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, 16.0f);
}

else
    MessageBox(NULL, "Failed to load texture", "End of the world", MB_OK | MB_ICONINFORMATION);

Код дисплея

glEnable(GL_TEXTURE_2D);    
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glBindTexture(GL_TEXTURE_2D, titleTex);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
glTranslatef(-800, 0, 0.0);
glColor3f(1,1,1);

glBegin(GL_QUADS);
    glTexCoord2f(0.0, 0.0); glVertex2f(0,0);
    glTexCoord2f(0.0, 1.0); glVertex2f(0,600);
    glTexCoord2f(1.0, 1.0); glVertex2f(1600,600);
    glTexCoord2f(1.0, 0.0); glVertex2f(1600,0);
glEnd();
glDisable(GL_BLEND);    
glDisable(GL_TEXTURE_2D);

РЕДАКТИРОВАТЬ: я не думаю, что я растягиваю каждый пиксель должно быть два в системе координат

int width=800, height=600;
int left = -400-(width-400);
int right = 400+(width-400);
int top = 400+(height-400);
int bottom = -400-(height-400);
gluOrtho2D(left,right,bottom,top);

Ответы [ 5 ]

4 голосов
/ 28 апреля 2010

OpenGL (обычно) потребует, чтобы сама текстура имела размер, равный степени 2, поэтому (вероятно) происходит то, что ваша текстура масштабируется до размера, где размеры имеют степень 2, затем сокращается до первоначального размера - в процессе двойного масштабирования вы теряете некоторое качество.

Вы, очевидно, просто хотите отобразить свое растровое изображение без какого-либо масштабирования, без переноса его на поверхность другого объекта или чего-либо подобного (то есть, для любых текстур, для которых предназначены текстуры). В таком случае я бы просто отобразил его как растровое изображение, а не текстуру (например, см. glRasterPos2i и glBitmap).

2 голосов
/ 28 апреля 2010

Я бы посоветовал сделать так, чтобы у png было разрешение в степени 2. Т.е. 1024x512 и поместите часть, которую вы хотите нарисовать, в верхнем левом углу по-прежнему в разрешении экрана. Затем измените масштаб texcoords на 800.0 / 1024.0 и 600.0 / 512.0, чтобы получить правильную часть текстуры. Я полагаю, что то, что происходит, glTexImage2D может иногда обрабатывать ширину и высоту, которые не являются степенью 2, но затем могут масштабировать входное изображение, фильтруя его.

Пример обработки этого можно посмотреть здесь (iPhone - OpenGLES - проект, который захватывает часть экрана без мощности 2 и переводит ее в текстуру 512x512 и масштабирует матрицу GL_TEXTURE строка 123 вместо ручного изменения масштаба текстовых строк)

Здесь - еще один пост, в котором упоминается этот метод.

2 голосов
/ 27 апреля 2010

Почему вы хотите использовать mipmapping и анизотропную фильтрацию для статического изображения на начальном экране?Выглядит маловероятным, что изображение будет повернуто (для чего нужна анизотропная фильтрация) или его размер будет действительно очень быстро изменяться во много раз (для чего нужно mipmapping).

Если текстура растягивается: попробуйте использовать GL_NEAREST дляваш GL_MAG_FILTER, в этом случае он может дать лучшие результаты (GL_LINEAR более точен, но имеет характер размытия).

Если текстура свернута: то же самое, попробуйте использовать GL_NEAREST_MIPMAP_NEAREST,или, что еще лучше, попробуйте не использовать mipmaps и GL_NEAREST (или GL_LINEAR, в зависимости от того, что даст лучший результат).

1 голос
/ 27 апреля 2010

Вот гипотеза:

Ваше окно имеет размер 800x600 (и, возможно, ваш фреймбуфер тоже), но ваша клиентская область - нет, из-за оконного оформления по бокам.

Таким образом, ваш кадровый буфер изменяется при перемещении в клиентскую область вашего окна. Можете ли вы проверить свой код создания окна?

0 голосов
/ 28 апреля 2010
  • Остерегайтесь точного размера клиентской области вашего окна.Дважды проверьте, что вы ожидаете, что это будет
  • Остерегайтесь правил выравнивания пикселей.Возможно, вам придется добавить 0,5 к вашим координатам x / y, чтобы попасть в центры пикселей.Описание для DirectX можно найти здесь - хотя правила OpenGL могут отличаться.
...