Хотя я согласен с тем, что было написано в комментариях об этом устаревшем коде OpenGL, проблема не имеет ничего общего с OpenGL по своей сути.Вы хотите нарисовать 1 прямоугольник с правильным соотношением сторон внутри другого прямоугольника с другим соотношением сторон.Вам просто нужно знать, где разместить вершины.
Как правило, с целью текстуры TEXTURE_2D
вы хотите, чтобы ваши координаты текстуры были 0-1 в обоих направлениях, если вы не планируете обрезать входное изображение.Было время, когда текстуры должны были иметь ширину и высоту, которые были степенью 2. Это было не так в течение очень долгого времени.Итак, удалите эти 2 строки:
width = power2(width);
height = power2(height);
Итак, первое, что нужно сделать, это правильно:
_textureCoords[0] = 1.0;
_textureCoords[1] = 1.0;
_textureCoords[2] = 1.0;
_textureCoords[3] = 0.0;
_textureCoords[4] = 0.0;
_textureCoords[5] = 0.0;
_textureCoords[6] = 0.0;
_textureCoords[7] = 1.0;
(Следовательно, этот код действительно труден для чтенияи это будет трудно поддерживать. Вы должны сделать координаты текстуры (и координаты вершины) равными struct
со значениями x
и y
, так что это имеет смысл. Сейчас не очевидно, что это 4 набора 2Dкоординаты (max, max), (max, min), (min, min), (min, max). Но я отвлекся.)
Далее, чтобы выяснить координаты текстуры, вам нужнознать, будет ли видео масштабироваться в соответствии с шириной или высотой.Для этого вы можете вычислить
double widthScaleRatio = displayWidth / imageWidth; // <- using this scale will guarantee the width of the new image is the same as the display's width, but might crop the height
double heightScaleRatio = displayHeight / imageHeight; // <- using this scale will guarantee the height of the new image is the same as the display's height but might crop the width
double scale = 1.0;
// If scaling by the widthScaleRatio makes the height too big, use the heightScaleRatio
// Otherwise use the widthScaleRatio
if (imageHeight * widthScaleRatio > displayHeight)
{
scale = heightScaleRatio;
}
else
{
scale = widthScaleRatio;
}
Теперь масштабируйте вашу ширину и высоту с помощью scale
:
double newWidth = imageWidth * scale;
double newHeight = imageHeight * scale;
и устанавливайте свои вершины на основе этого:
_vertexes[0] = newWidth;
_vertexes[1] = newHeight;
_vertexes[2] = newWidth;
_vertexes[3] = 0.0;
_vertexes[4] = 0.0;
_vertexes[5] = 0.0;
_vertexes[6] = 0.0;
_vertexes[7] = newHeight;
То же самое относится и к тому, чтобы сделать этот код более легким для чтения, как и с координатами текстуры.
РЕДАКТИРОВАТЬ: Вот простая программа, чтобы показать, как она работает:
int main(){
double displayWidth = 2160;
double displayHeight = 4096;
double imageWidth = 640;
double imageHeight = 480;
double widthScaleRatio = displayWidth / imageWidth; // <- using this scale will guarantee the width of the new image is the same as the display's width, but might crop the height
double heightScaleRatio = displayHeight / imageHeight; // <- using this scale will guarantee the height of the new image is the same as the display's height but might crop the width
double scale = 1.0;
// If scaling by the widthScaleRatio makes the height too big, use the heightScaleRatio
// Otherwise use the widthScaleRatio
if (imageHeight * widthScaleRatio > displayHeight)
{
scale = heightScaleRatio;
}
else
{
scale = widthScaleRatio;
}
double newWidth = imageWidth * scale;
double newHeight = imageHeight * scale;
std::cout << "New size = (" << newWidth << ", " << newHeight << ")\n";
}
Когда я запускаю его, я получаю:
Новый размер = (2160, 1620)