Questions about ES2/GL3 shaders

All topics about ZGameEditor goes here.

Moderator: Moderators

User avatar
Ats
Posts: 770
Joined: Fri Sep 28, 2012 10:05 am
Contact:

Re: Questions about ES2/GL3 shaders

Post by Ats »

Image
Matrixes... :roll:
Yeah, I saw you complain here and there regarding matrix and shaders already.

Thanks for your example. So I played a bit with it in order to comprehend how it's working. I guess I need to do the same on all three axes, right? But I'm struggling with the Z axis rotation. Then I searched through the forum for other Matrix examples, then I discovered that one could "add from library" by right-clicking the Project Tree in ZGE. That's a neat but really hidden feature... :lol:

So now I'm playing with the Matrix Library, trying to get the correct rotation on all three axes from that.
User avatar
Ats
Posts: 770
Joined: Fri Sep 28, 2012 10:05 am
Contact:

Re: Questions about ES2/GL3 shaders

Post by Ats »

I managed to get a correct rotation transformation on all three axes with the Matrix Library. I had to multiply the matrices in a certain order (I'm discovering matrices here).

Code: Select all

<?xml version="1.0" encoding="iso-8859-1" ?>
<ZApplication Name="App" Caption="ZGameEditor application" ClearColor="0.5 0.5 0.5 1" CameraPosition="-7.2006 2 3.4859" CameraRotation="0 1.1782 0" RenderOrder="1" FileVersion="2">
  <OnLoaded>
    <ZLibrary Comment="Matrix Library">
      <Source>
<![CDATA[// Returns a identity matrix.

mat4 matrixIdentity()
{
  mat4 m;

  m[0,0] = 1;
  m[1,1] = 1;
  m[2,2] = 1;
  m[3,3] = 1;

  return m;
}

// Returns a translation matrix.

mat4 matrixFromTranslation(vec3 translation)
{
  mat4 m;

  m[0,0] = 1;
  m[1,1] = 1;
  m[2,2] = 1;
  m[3,3] = 1;

  m[3,0] = translation.x;
  m[3,1] = translation.y;
  m[3,2] = translation.z;

  return m;
}

// Returns a scale matrix.

mat4 matrixFromScale(vec3 scale)
{
  mat4 m;

  m[0,0] = scale.x;
  m[1,1] = scale.y;
  m[2,2] = scale.z;
  m[3,3] = 1;

  return m;
}

// Returns a x-axis rotation matrix.

mat4 matrixFromRotationX(float angle)
{
  angle *= PI*2;

  float s = sin(angle);
  float c = cos(angle);

  mat4 m;

  m[1,1] = c; m[2,1] = 0-s;
  m[1,2] = s; m[2,2] = c;

  m[0,0] = 1;
  m[3,3] = 1;

  return m;
}

// Returns a y-axis rotation matrix.

mat4 matrixFromRotationY(float angle)
{
  angle *= PI*2;

  float s = sin(angle);
  float c = cos(angle);

  mat4 m;

  m[0,0] = c;   m[2,0] = s;
  m[0,2] = 0-s; m[2,2] = c;

  m[1,1] = 1;
  m[3,3] = 1;

  return m;
}

// Returns a z-axis rotation matrix.

mat4 matrixFromRotationZ(float angle)
{
  angle *= PI*2;

  float s = sin(angle);
  float c = cos(angle);

  mat4 m;

  m[0,0] = c; m[1,0] = 0-s;
  m[0,1] = s; m[1,1] = c;

  m[2,2] = 1;
  m[3,3] = 1;

  return m;
}

// Returns a euler-angles matrix.

mat4 matrixFromEuler(vec3 rotation)
{
  float sx, cx, sy, cy, sz, cz;

  // Would have been nice if you could do "rotation *= PI*2" :-(
  rotation.x *= PI*2;
  rotation.y *= PI*2;
  rotation.z *= PI*2;

  sx = sin(rotation.x);
  cx = cos(rotation.x);

  sy = sin(rotation.y);
  cy = cos(rotation.y);

  sz = sin(rotation.z);
  cz = cos(rotation.z);

  mat4 m;

  m[0,0] = cy*cz; m[1,0] = sx*cz*sy-cx*sz; m[2,0] = cx*cz*sy+sx*sz;
  m[0,1] = cy*sz; m[1,1] = sx*sz*sy+cx*cz; m[2,1] = cx*sz*sy-sx*cz;
  m[0,2] = 0-sy;  m[1,2] = sx*cy;          m[2,2] = cx*cy;

  m[3,3] = 1;

  return m;
}

// Returns a axis-angle matrix.

mat4 matrixFromAxisAngle(vec3 axis, float angle)
{
  float s, c, x, y, z, t;

  angle *= PI*2;

  s = sin(angle);
  c = cos(angle);

  x = axis.x;
  y = axis.y;
  z = axis.z;

  t = 1-c;

  mat4 m;

  m[0,0] = t*x*x+c;   m[1,0] = t*x*y-s*z; m[2,0] = t*x*z+s*y;
  m[0,1] = t*x*y+s*z; m[1,1] = t*y*y+c;   m[2,1] = t*y*z-s*x;
  m[0,2] = t*x*z-s*y; m[1,2] = t*y*z+s*x; m[2,2] = t*z*z+c;

  m[3,3] = 1;

  return m;
}

// Returns a quaternion matrix.

mat4 matrixFromQuaternion(vec4 quaternion)
{
  float x, y, z, w, x2, y2, z2;

  x = quaternion.x;
  y = quaternion.y;
  z = quaternion.z;
  w = quaternion.w;

  x2 = x+x;
  y2 = y+y;
  z2 = z+z;

  mat4 m;

  m[0,0] = 1-(y*y2+z*z2); m[1,0] =    x*y2-w*z2;  m[2,0] =    x*z2+w*y2;
  m[0,1] =    x*y2-w*z2;  m[1,1] = 1-(x*x2+z*z2); m[2,1] =    y*z2-w*x2;
  m[0,2] =    x*z2-w*y2;  m[1,2] =    y*z2+w*x2;  m[2,2] = 1-(x*x2+y*y2);

  m[3,3] = 1;

  return m;
}

// Returns a model matrix.

mat4 matrixFromModel(model q)
{
  // Would have been nice if you could do "mat4 m = matrixFromEuler(q.rotation)" :-(
  vec3 rotation = vector3(q.rotation.x, q.rotation.y, q.rotation.z);
  mat4 m = matrixFromEuler(rotation);

  m[3,0] = q.position.x;
  m[3,1] = q.position.y;
  m[3,2] = q.position.z;

  for(int i=0; i<3; i++)
  {
    m[0,i] *= q.scale.x;
    m[1,i] *= q.scale.y;
    m[2,i] *= q.scale.z;
  }

  return m;
}]]>
      </Source>
    </ZLibrary>
    <SpawnModel Model="Box"/>
  </OnLoaded>
  <OnRender>
    <ZExpression>
      <Expression>
<![CDATA[// Get the current modelViewMatrix ( which contains the viewMatrix at this point )

getMatrix(0, ViewMatrix);]]>
      </Expression>
    </ZExpression>
  </OnRender>
  <Content>
    <Variable Name="ViewMatrix" Type="5"/>
    <Model Name="Box">
      <OnUpdate>
        <ZExpression>
          <Expression>
<![CDATA[// Animate the box

Box.Position.Y = abs(sin(App.Time))*2.5+1;
Box.Position.X = sin(App.Time)*2;
Box.Position.Z = cos(App.Time)*2;
Box.Rotation.X = App.Time/PI;
Box.Rotation.Y = App.Time/PI;
Box.Rotation.Z = App.Time/PI;]]>
          </Expression>
        </ZExpression>
      </OnUpdate>
      <OnRender>
        <UseMaterial Material="BoxMaterial"/>
        <RenderMesh Mesh="BoxMesh"/>
        <ZExpression>
          <Expression>
<![CDATA[
mat4 mt = matrixFromTranslation(vector3(CurrentModel.Position.X, 0, CurrentModel.Position.Z));
mat4 ms = matrixFromScale(vector3(1,0,1));
mat4 mx = matrixFromRotationX(CurrentModel.Rotation.X);
mat4 my = matrixFromRotationY(CurrentModel.Rotation.Y);
mat4 mz = matrixFromRotationZ(CurrentModel.Rotation.Z);
setMatrix(0, ViewMatrix * mt * ms * mz * my * mx);]]>
          </Expression>
        </ZExpression>
        <RenderMesh Mesh="BoxMesh"/>
      </OnRender>
    </Model>
    <Mesh Name="BoxMesh">
      <Producers>
        <MeshBox/>
        <MeshBox Scale="2 0.1 0.1"/>
        <MeshCombine/>
        <MeshBox Scale="0.4 1.5 0.4"/>
        <MeshCombine/>
      </Producers>
    </Mesh>
    <Material Name="BoxMaterial" Shading="2" Light="0"/>
  </Content>
</ZApplication>
Now I'm going to try with what Kjell sent me :wink:
Post Reply