OpenGL: scale then translate? and how?

前端 未结 3 1558
野的像风
野的像风 2020-12-02 14:42

I\'ve got some 2D geometry. I want to take some bounding rect around my geometry, and then render a smaller version of it somewhere else on the plane. Here\'s more or less t

相关标签:
3条回答
  • 2020-12-02 15:14

    Scale, just like Rotate, operates from the origin. so if you scale by half an object that spans the segment [10:20] (on axis X, e.g.), you get [5:10]. The object therefore was scaled, and moved closer to the origin. Exactly what you observed.

    This is why you apply Scale first in general (because objects tend to be defined around 0).

    So if you want to scale an object around point Center, you can translate the object from Center to the origin, scale there, and translate back.

    Side note, if you translate first, and then scale, then your scale is applied to the previous translation, which is why you probably had issues with this method.

    0 讨论(0)
  • 2020-12-02 15:29

    I haven't played with OpenGL ES, just a bit with OpenGL.

    It sounds like you want to transform from a different position as opposed to the origin, not sure, but can you try to do the transforms and draws that bit within glPushMatrix() and glPopMatrix() ?

    e.g.
    
    // source and dest are arbitrary rectangles.
    float scaleX = dest.width / source.width;
    float scaleY = dest.height / source.height;
    float translateX = dest.x - source.x;
    float translateY = dest.y - source.y;
    
    glPushMatrix();
      glScalef(scaleX, scaleY, 0.0);
      glTranslatef(translateX, translateY, 0.0);
      // Draw geometry in question with its normal verts.
      //as if it were drawn from 0,0
    glPopMatrix();
    

    Here's a simple Processing sketch I wrote to illustrate the point:

    import processing.opengl.*;
    import javax.media.opengl.*;
    
    
    void setup() {
      size(500, 400, OPENGL);
    }
    
    void draw() {
      background(255);
      PGraphicsOpenGL pgl = (PGraphicsOpenGL) g;
      GL gl = pgl.beginGL();  
    
    
      gl.glPushMatrix();
        //transform the 'pivot'
        gl.glTranslatef(100,100,0);
        gl.glScalef(10,10,10);
        //draw something from the 'pivot'
        gl.glColor3f(0, 0.77, 0);
        drawTriangle(gl);
      gl.glPopMatrix();
      //matrix poped, we're back to orginin(0,0,0), continue as normal
      gl.glColor3f(0.77, 0, 0);
      drawTriangle(gl);
      pgl.endGL();
    }
    
    void drawTriangle(GL gl){
      gl.glBegin(GL.GL_TRIANGLES);
      gl.glVertex2i(10, 0);
      gl.glVertex2i(0, 20);
      gl.glVertex2i(20, 20);
      gl.glEnd();
    }
    

    Here is an image of the sketch running, the same green triangle is drawn, with translation and scale applied, then the red one, outsie the push/pop 'block', so it is not affected by the transform:

    alt text

    HTH, George

    0 讨论(0)
  • 2020-12-02 15:30

    In OpenGL, matrices you specify are multiplied to the right of the existing matrix, and the vertex is on the far right of the expression.

    Thus, the last operation you specify are in the coordinate system of the geometry itself. (The first is usually the view transform, i.e. inverse of your camera's to-world transform.)

    Bahbar makes a good point that you need to consider the center point for scaling. (or the pivot point for rotations.) Usually you translate there, rotate/scale, then translate back. (or in general, apply basis transform, the operation, then the inverse). This is called Change of Basis, which you might want to read up on.

    Anyway, to get some intuition about how it works, try with some simple values (zero, etc) then alter them slightly (perhaps an animation) and see what happens with the output. Then it's much easier to see what your transforms are actually doing to your geometry.

    Update

    That the order is "reversed" w.r.t. intuition is rather common among beginner OpenGL-coders. I've been tutoring a computer graphics course and many react in a similar manner. It becomes easier to think about how OpenGL does it if you consider the use of pushmatrix/popmatrix while rendering a tree (scene-graph) of transforms and geometries. Then the current order-of-things becomes rather natural, and the opposite would make it rather difficult to get anything useful done.

    0 讨论(0)
提交回复
热议问题