gpt4 book ai didi

ios - openGL 缩放/旋转(先发生什么......)

转载 作者:行者123 更新时间:2023-11-30 17:22:34 25 4
gpt4 key购买 nike

最近,我开始使用 openGL。大多数事情都进展顺利,但我总是用头撞墙。

我正在尝试旋转/缩放 2D 图像。我正在努力解决这样一个事实:我应该先旋转,然后缩放,或者反之亦然。这两种方式都不太符合我想要的方式。

我制作了两个短视频来展示问题所在:

先旋转,再缩放 https://dl.dropboxusercontent.com/u/992980/rotate_then_scale.MOV

先缩放,再旋转 https://dl.dropboxusercontent.com/u/992980/scale_then_rotate.MOV

左图是正方形,右图是长方形。正如您所看到的,这两种方法都不太正确:)

黑色区域是openGL视口(viewport)。当视口(viewport)是正方形时,一切都很好,当它是矩形时,事情开始出错:)对于我绘制的每个图像,我引用视口(viewport)计算不同的 X 和 Y 比例,我认为我正在做一些事情那里错了...请注意,我对 openGL 还很陌生,我可能正在做一些愚蠢的事情(我希望我是)。希望我能通过这种方式清楚地表达我的问题。

预先感谢您提供的任何帮助!

科里安

绘制一张图像的代码:

void instrument_renderer_image_draw_raw(struct InstrumentRenderImage* image, struct InstrumentRendererCache* cache, GLuint program) {

// Load texture if not yet done
if (image->loaded == INSTRUMENT_RENDER_TEXTURE_UNLOADED) {
image->texture = instrument_renderer_texture_cache_get(image->imagePath);

if (image->texture == 0) {
image->loaded = INSTRUMENT_RENDER_TEXTURE_ERROR;
}
else {
image->loaded = INSTRUMENT_RENDER_TEXTURE_LOADED;
}
}

// Show image when texture has been correctly loaded into GPU memory
if (image->loaded == INSTRUMENT_RENDER_TEXTURE_LOADED) {

float instScaleX = (float)cache->instBounds.w / cache->instOrgBounds.w;
float instScaleY = (float)cache->instBounds.h / cache->instOrgBounds.h;

float scaleX = (float)image->w / (float)cache->instOrgBounds.w;
float scaleY = (float)image->h / (float)cache->instOrgBounds.h;

// Do internal calculations when dirty
if (image->base.dirty) {

mat4 matScale;
mat4 matRotate;
mat4 matModelView;
mat4 matProjection;

matrixRotateZ(image->angle, matRotate);

matrixScale(scaleX , scaleY * -1, 0, matScale);

matrixMultiply(matRotate, matScale, matModelView);

// Determine X and Y within this instrument's viewport
float offsetX = ((float)cache->instOrgBounds.w - (float)image->w) / 2 / (float)cache->instOrgBounds.w;
float offsetY = ((float)cache->instOrgBounds.h - (float)image->h) / 2 / (float)cache->instOrgBounds.h;

float translateX = ( ((float)image->x / (float)cache->instOrgBounds.w) - offsetX) * 2;
float translateY = ( ( ( (float)cache->instOrgBounds.h - (float)image->y - (float)image->h ) / (float)cache->instOrgBounds.h) - offsetY) * -2;

matrixTranslate(translateX, translateY*-1, -2.4,matModelView);

//matrixPerspective(45.0, 0.1, 100.0, (double)cache->instOrgBounds.w/(double)cache->instOrgBounds.h, matProjection);
matrixOrthographic(-1, 1, -1, 1, matProjection);

matrixMultiply(matProjection, matModelView, image->glMatrix);

image->base.dirty = 0;
}

glUseProgram(program);

glViewport(cache->instBounds.x * cache->masterScaleX,
cache->instBounds.y * cache->masterScaleY,
cache->instBounds.w * cache->masterScaleX,
cache->instBounds.w * cache->masterScaleX);

glUniformMatrix4fv(matrixUniform, 1, GL_FALSE, image->glMatrix);

// Load texture
glBindTexture(GL_TEXTURE_2D, image->texture);

glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
}

最佳答案

您使用什么框架/库进行矩阵乘法?

首先需要考虑的事情取决于您的矩阵表示(例如行优先与列优先以及后乘与预乘)。您使用的库规定了这一点;固定函数 OpenGL(glMultMatrix (...) et al.)是列优先和后乘法。大多数基于 OpenGL 的框架都遵循传统,但也有一些异常(exception),例如 OpenTK。传统的矩阵乘法按以下顺序完成:

1. Translation
2. Scaling
3. Rotation

但是由于后乘列主矩阵的性质(矩阵乘法是不可交换的),操作实际上是从下到上发生的。即使您在旋转乘法之前进行平移乘法,但旋转实际上会应用于预翻译的坐标。

实际上,假设您的矩阵库遵循 OpenGL 约定,您将执行相反的矩阵乘法顺序。

关于ios - openGL 缩放/旋转(先发生什么......),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27999758/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com