2015-01-17 3 views
0

Недавно я прыгнул в openGL. У большинства вещей все в порядке, но я продолжаю стучать головой о стену с этим.openGL масштабирование/вращение (что на первом месте)

Я пытаюсь повернуть/масштабировать 2D-изображение. Я борюсь с тем, что сначала должен вращаться, а затем масштабироваться или наоборот. Оба способа не совсем работают так, как я хочу.

Я сделал два коротких видео, показывающим, что это происходит не так:

Первых вращаться, затем масштабировать https://dl.dropboxusercontent.com/u/992980/rotate_then_scale.MOV

Первого масштаб, затем поверните https://dl.dropboxusercontent.com/u/992980/scale_then_rotate.MOV

Левого изображения является квадратом, право Изображение представляет собой прямоугольник. Как вы можете видеть, с помощью обоих методов что-то не совсем правильно:

Черная область - это окно просмотра openGL. Когда область просмотра квадратная, все в порядке, когда это прямоугольник, все начинает идти не так :) Для каждого рисунка я рисую, я вычисляю другую шкалу X и Y по отношению к окну просмотра, я думаю, что делаю что-то неправильно там ... Обратите внимание, что я совершенно новый для openGL, и я, вероятно, делаю что-то глупое (надеюсь, что я). Надеюсь, я смогу четко разобраться в этом вопросе.

Заранее благодарим за любую помощь!

Corjan

код для рисования одного изображения:

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); 
} 
+2

По крайней мере, для меня ссылки не работают. – henje

+0

То же самое для меня. Было бы здорово, если бы вы могли описать немного больше того, что происходит в видео. Даже если вы исправите их сейчас, вы в конечном итоге удалите видео из своего Dropbox. Но если вы их описываете (или вставляете изображения), это может помочь другим людям в будущем. – Jerem

+0

К сожалению, для загрузки видео требуется секундомер. Теперь они работают –

ответ

0

Какие рамки/библиотека, которую вы используете для матричного умножения?

Вещь, которая должна быть первой, зависит от вашего матричного представления (, например, row- vs. column-major и post-vs. pre-multipication). Используемая вами библиотека диктует это; фиксированная функция OpenGL (glMultMatrix (...)и др.) была главной и пост-умноженной. Большинство основанных на OpenGL фреймворков следуют традиции, хотя есть некоторые исключения, такие как OpenTK. Традиционные матричные умножения были сделаны в следующем порядке:

1. Translation 
2. Scaling 
3. Rotation 

Но из-за природы после умножения столбцов матриц (умножение матриц некоммутативно) операции эффективно происходило снизу-вверх. Несмотря на то, что вы выполняете умножение для перевода перед тем, которое требуется для вращения, на самом деле применяется преобразование в заранее переведенные координаты.

Фактически, если ваша матричная библиотека соответствует соглашению OpenGL, вы выполняете последовательность матричных умножений в обратном порядке.

+0

. Единая матрица масштабирования и матрица чистого вращения являются коммутативными **, если ** нет ошибок округления. –

+0

@ratchetfreak: матрица matModelView в этом примере включает ненулевой перевод. Я знаю, что заголовок вопроса только спрашивает о порядке масштабирования и вращения, но тот факт, что перевод введен 4 строки над 'image-> base.dirty = 0', касается меня. –

+0

Спасибо за ваш ответ в первую очередь! Вполне возможно, что я делаю вещи в неправильном порядке ... Я рассматривал этот учебник как ориентир (http://blog.db-in.com/cameras-on-opengl-es-2-x/). Это файл c, который обрабатывает все мультиссылки (https://dl.dropboxusercontent.com/u/992980/Utils.h). Я не уверен, если это колонка-майор, снизу-вверх или что-то, хотя :) Боюсь, что мое понимание таких вещей довольно ограничено. –

Смежные вопросы