commit 49355f257014b4c39c13e88b00b2f331b6ea6a2d
Author: leszek <leszek@koltunski.pl>
Date:   Sun Apr 20 00:29:38 2025 +0200

    the 'program' package converted to Kotlin.

diff --git a/src/main/java/org/distorted/library/program/DistortedProgram.kt b/src/main/java/org/distorted/library/program/DistortedProgram.kt
index df658fc..4be589f 100644
--- a/src/main/java/org/distorted/library/program/DistortedProgram.kt
+++ b/src/main/java/org/distorted/library/program/DistortedProgram.kt
@@ -18,575 +18,558 @@
 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA                //
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-package org.distorted.library.program;
+package org.distorted.library.program
 
-import android.opengl.GLES30;
-
-import org.distorted.library.main.DistortedLibrary;
-
-import java.io.BufferedReader;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
+import android.opengl.GLES30
+import org.distorted.library.main.DistortedLibrary
+import java.io.BufferedReader
+import java.io.IOException
+import java.io.InputStream
+import java.io.InputStreamReader
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
-/**
- * An object which encapsulates a vertex/fragment shader combo, aka Shader Program.
- */
-public class DistortedProgram
-  {
-  public static final int ATTR_LAYOUT_PNTC = 0;
-  public static final int ATTR_LAYOUT_PTC  = 1;
-  public static final int ATTR_LAYOUT_PNT  = 2;
-  public static final int ATTR_LAYOUT_PNC  = 3;
-  public static final int ATTR_LAYOUT_PT   = 4;
-  public static final int ATTR_LAYOUT_P    = 5;
-  public static final int ATTR_LAYOUT_UNK  = 6;
-
-  private String mAttributeStr, mUniformStr, mUniList;
-  private int mAttributeLen, mUniformLen;
-  private int mNumAttributes;
-  private int mNumUniforms;
-  private String[] mAttributeName;
-  private final int mProgramHandle;
-
-/**
- * Various programs have different attributes (because even if the source is the same, some of them might
- * be unused).
- * Main, Full have 4 attributes in the order (position,normal,texcoord, component)
- * Pre has 3 attributes (position,texcoord,component)
- * Maybe there are other possibilities (only position and normal? 3- position,normal,texcoord?)
- */
-  public int mAttributeLayout;
-/**
- * List of Attributes (OpenGL ES 3.0: 'in' variables), in the same order as declared in the shader source.
- */
-  public int[] mAttribute;
-/**
- * List of Uniforms, in the same order as declared in the shader source.
- */
-  public int[] mUniform;
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private int createAndLinkProgram(final int vertexShaderHandle, final int fragmentShaderHandle, final String[] attributes, final String[] feedbackVaryings)
-  throws LinkingException
+/** An object which encapsulates a vertex/fragment shader combo, aka Shader Program.
+*/
+class DistortedProgram
+{
+    private var mAttributeStr: String? = null
+    private var mUniformStr: String? = null
+    private var mUniList: String? = null
+    private var mAttributeLen = 0
+    private var mUniformLen = 0
+    private var mNumAttributes = 0
+    private var mNumUniforms = 0
+    private lateinit var mAttributeName: Array<String>
+    val programHandle: Int
+
+    /**
+     * Various programs have different attributes (because even if the source is the same, some of them might
+     * be unused).
+     * Main, Full have 4 attributes in the order (position,normal,texcoord, component)
+     * Pre has 3 attributes (position,texcoord,component)
+     * Maybe there are other possibilities (only position and normal? 3- position,normal,texcoord?)
+     */
+    @JvmField var mAttributeLayout: Int = 0
+
+    /**
+     * List of Attributes (OpenGL ES 3.0: 'in' variables), in the same order as declared in the shader source.
+     */
+    @JvmField var mAttribute: IntArray? = null
+
+    /**
+     * List of Uniforms, in the same order as declared in the shader source.
+     */
+    @JvmField var mUniform: IntArray? = null
+
+    ///////////////////////////////////////////////////////////////////////////////////////////////
+    @Throws(LinkingException::class)
+    private fun createAndLinkProgram(verHandle: Int, fraHandle: Int, attributes: Array<String>?, feedbackVaryings: Array<String?>?): Int
     {
-    int programHandle = GLES30.glCreateProgram();
+        val programHandle = GLES30.glCreateProgram()
 
-    if (programHandle != 0)
-      {
-      GLES30.glAttachShader(programHandle, vertexShaderHandle);
-      GLES30.glAttachShader(programHandle, fragmentShaderHandle);
-
-      if( feedbackVaryings!=null )
+        if (programHandle != 0)
         {
-        GLES30.glTransformFeedbackVaryings(programHandle, feedbackVaryings, GLES30.GL_INTERLEAVED_ATTRIBS);
-        }
+            GLES30.glAttachShader(programHandle, verHandle)
+            GLES30.glAttachShader(programHandle, fraHandle)
 
-      if (attributes != null)
-        {
-        final int size = attributes.length;
+            if (feedbackVaryings != null)
+                GLES30.glTransformFeedbackVaryings(programHandle, feedbackVaryings, GLES30.GL_INTERLEAVED_ATTRIBS)
 
-        for(int i=0; i<size; i++)
-          {
-          GLES30.glBindAttribLocation(programHandle, i, attributes[i]);
-          }
-        }
+            if (attributes != null)
+            {
+                val size = attributes.size
 
-      GLES30.glLinkProgram(programHandle);
+                for (i in 0..<size)
+                    GLES30.glBindAttribLocation(programHandle, i, attributes[i])
+            }
 
-      final int[] linkStatus = new int[1];
-      GLES30.glGetProgramiv(programHandle, GLES30.GL_LINK_STATUS, linkStatus, 0);
+            GLES30.glLinkProgram(programHandle)
 
-      if (linkStatus[0] != GLES30.GL_TRUE )
-        {
-        String error = GLES30.glGetProgramInfoLog(programHandle);
-        GLES30.glDeleteProgram(programHandle);
-        throw new LinkingException(error);
-        }
+            val linkStatus = IntArray(1)
+            GLES30.glGetProgramiv(programHandle, GLES30.GL_LINK_STATUS, linkStatus, 0)
 
-      //final int[] numberOfUniforms = new int[1];
-      //GLES30.glGetProgramiv(programHandle, GLES30.GL_ACTIVE_UNIFORMS, numberOfUniforms, 0);
-      //DistortedLibrary.logMessage("DistortedProgram: number of active uniforms="+numberOfUniforms[0]);
-      }
+            if (linkStatus[0] != GLES30.GL_TRUE)
+            {
+                val error = GLES30.glGetProgramInfoLog(programHandle)
+                GLES30.glDeleteProgram(programHandle)
+                throw LinkingException(error)
+            }
 
-    return programHandle;
-    }
+            //final int[] numberOfUniforms = new int[1];
+            //GLES30.glGetProgramiv(programHandle, GLES30.GL_ACTIVE_UNIFORMS, numberOfUniforms, 0);
+            //DistortedLibrary.logMessage("DistortedProgram: number of active uniforms="+numberOfUniforms[0]);
+        }
 
-///////////////////////////////////////////////////////////////////////////////////////////////////
+        return programHandle
+    }
 
-  private void init(int glslVersion)
+    ///////////////////////////////////////////////////////////////////////////////////////////////
+    private fun init(glslVersion: Int)
     {
-    mAttributeStr  = (glslVersion == 100 ? "attribute " : "in ");
-    mAttributeLen  = mAttributeStr.length();
-    mNumAttributes = 0;
-    mUniformStr    = "uniform ";
-    mUniformLen    = mUniformStr.length();
-    mNumUniforms   = 0;
-    mUniList       = "";
+        mAttributeStr = (if (glslVersion==100) "attribute " else "in ")
+        mAttributeLen = mAttributeStr!!.length
+        mNumAttributes = 0
+        mUniformStr = "uniform "
+        mUniformLen = mUniformStr!!.length
+        mNumUniforms = 0
+        mUniList = ""
     }
 
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private String parseOutUniform(final String line)
+    ///////////////////////////////////////////////////////////////////////////////////////////////
+    private fun parseOutUniform(line: String): String?
     {
-    int len = line.length();
-    int whiteSpace, semicolon, nameBegin;
-    char currChar;
-
-    for(whiteSpace=0; whiteSpace<len; whiteSpace++)
-      {
-      currChar = line.charAt(whiteSpace);
-      if( currChar!=' ' && currChar!='\t') break;
-      }
-
-    for(semicolon=whiteSpace; semicolon<len; semicolon++)
-      {
-      currChar = line.charAt(semicolon);
-      if( currChar==';') break;
-      }
-
-    if( semicolon<len && semicolon-whiteSpace>=mUniformLen+1 )
-      {
-      String subline = line.substring(whiteSpace,semicolon);
-      int subLen = semicolon-whiteSpace;
-
-      if( subline.startsWith(mUniformStr))
-        {
-        //DistortedLibrary.logMessage("DistortedProgram: GOOD LINE: " +subline+" subLen="+subLen);
+        val len = line.length
+        var semicolon: Int
+        var nameBegin: Int
+        var currChar: Char
+        var whiteSpace = 0
 
-        for(nameBegin=subLen-1; nameBegin>mUniformLen-2; nameBegin--)
-          {
-          currChar=subline.charAt(nameBegin);
-
-          if( currChar==' ' || currChar=='\t' )
-            {
-            mNumUniforms++;
-            String uniform = subline.substring(nameBegin+1,subLen);
-            int brace = uniform.indexOf("[");
-
-            return brace>=0 ? uniform.substring(0,brace) : uniform;
-            }
-          }
+        while (whiteSpace < len)
+        {
+            currChar = line[whiteSpace]
+            if (currChar != ' ' && currChar != '\t') break
+            whiteSpace++
         }
-      }
 
-    return null;
-    }
+        semicolon = whiteSpace
 
-///////////////////////////////////////////////////////////////////////////////////////////////////
+        while (semicolon < len)
+        {
+            currChar = line[semicolon]
+            if (currChar == ';') break
+            semicolon++
+        }
 
-  private String parseOutAttribute(final String line)
-    {
-    int len = line.length();
-    int whiteSpace, semicolon, nameBegin;
-    char currChar;
-
-    for(whiteSpace=0; whiteSpace<len; whiteSpace++)
-      {
-      currChar = line.charAt(whiteSpace);
-      if( currChar!=' ' && currChar!='\t') break;
-      }
-
-    for(semicolon=whiteSpace; semicolon<len; semicolon++)
-      {
-      currChar = line.charAt(semicolon);
-      if( currChar==';') break;
-      }
-
-    if( semicolon<len && semicolon-whiteSpace>=mAttributeLen+1 )
-      {
-      String subline = line.substring(whiteSpace,semicolon);
-      int subLen = semicolon-whiteSpace;
-
-      if( subline.startsWith(mAttributeStr))
+        if (semicolon < len && semicolon-whiteSpace >= mUniformLen+1)
         {
-        for(nameBegin=subLen-1; nameBegin>mAttributeLen-2; nameBegin--)
-          {
-          currChar=subline.charAt(nameBegin);
+            val subline = line.substring(whiteSpace, semicolon)
+            val subLen = semicolon - whiteSpace
 
-          if( currChar==' ' || currChar=='\t' )
+            if (subline.startsWith(mUniformStr!!))
             {
-            return subline.substring(nameBegin+1,subLen);
+                nameBegin = subLen-1
+
+                while (nameBegin > mUniformLen-2)
+                {
+                    currChar = subline[nameBegin]
+
+                    if (currChar == ' ' || currChar == '\t')
+                    {
+                        mNumUniforms++
+                        val uniform = subline.substring(nameBegin+1, subLen)
+                        val brace = uniform.indexOf("[")
+                        return if (brace>=0) uniform.substring(0, brace) else uniform
+                    }
+                    nameBegin--
+                }
             }
-          }
         }
-      }
 
-    return null;
+        return null
     }
 
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private void doAttributes(final String shader, boolean doAttributes)
+    ///////////////////////////////////////////////////////////////////////////////////////////////
+    private fun parseOutAttribute(line: String): String?
     {
-    String attribute, attrList="", uniform;
-    String[] lines = shader.split("\n");
+        val len = line.length
+        var semicolon: Int
+        var nameBegin: Int
+        var currChar: Char
+        var whiteSpace = 0
 
-    for (String line : lines)
-      {
-      if( doAttributes )
+        while (whiteSpace<len)
         {
-        attribute = parseOutAttribute(line);
-
-        if (attribute != null)
-          {
-          if( !attrList.isEmpty() ) attrList += " ";
-          attrList += attribute;
-          }
+            currChar = line[whiteSpace]
+            if (currChar != ' ' && currChar != '\t') break
+            whiteSpace++
         }
 
-      uniform = parseOutUniform(line);
+        semicolon = whiteSpace
 
-      if (uniform != null)
+        while (semicolon < len)
         {
-        if( !mUniList.isEmpty() ) mUniList += " ";
-        mUniList += uniform;
+            currChar = line[semicolon]
+            if (currChar == ';') break
+            semicolon++
         }
-      }
 
-    if( doAttributes )
-      {
-      mAttributeName = attrList.split(" ");
-      mNumAttributes = mAttributeName.length;
-      }
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private String readTextFileFromRawResource(final InputStream inputStream, boolean doAttributes)
-    {
-    final InputStreamReader inputStreamReader = new InputStreamReader(inputStream);
-    final BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
-
-    String nextLine, attribute, attrList="";
-    final StringBuilder body = new StringBuilder();
-
-    try
-      {
-      while ((nextLine = bufferedReader.readLine()) != null)
+        if (semicolon < len && semicolon-whiteSpace >= mAttributeLen+1)
         {
-        body.append(nextLine);
-        body.append('\n');
+            val subline = line.substring(whiteSpace, semicolon)
+            val subLen = semicolon-whiteSpace
 
-        if( doAttributes )
-          {
-          attribute = parseOutAttribute(nextLine);
-
-          if( attribute!=null )
+            if (subline.startsWith(mAttributeStr!!))
             {
-            //DistortedLibrary.logMessage("DistortedProgram: new attribute: "+attribute);
-            if( !attrList.isEmpty() ) attrList += " ";
-            attrList += attribute;
+                nameBegin = subLen-1
+
+                while (nameBegin > mAttributeLen-2)
+                {
+                    currChar = subline[nameBegin]
+                    if (currChar == ' ' || currChar == '\t') return subline.substring(nameBegin + 1, subLen)
+                    nameBegin--
+                }
             }
-          }
         }
-      }
-    catch (IOException e)
-      {
-      return null;
-      }
-
-    if( doAttributes )
-      {
-      mAttributeName = attrList.split(" ");
-      mNumAttributes = mAttributeName.length;
-      }
-
-    return body.toString();
-    }
 
-///////////////////////////////////////////////////////////////////////////////////////////////////
+        return null
+    }
 
-  private static int compileShader(final int shaderType, final String shaderSource)
-  throws FragmentCompilationException,VertexCompilationException
+    ///////////////////////////////////////////////////////////////////////////////////////////////
+    private fun doAttributes(shader: String, doAttributes: Boolean)
     {
-    int shaderHandle = GLES30.glCreateShader(shaderType);
-
-    if (shaderHandle != 0)
-      {
-      GLES30.glShaderSource(shaderHandle, shaderSource);
-      GLES30.glCompileShader(shaderHandle);
-      final int[] compileStatus = new int[1];
-      GLES30.glGetShaderiv(shaderHandle, GLES30.GL_COMPILE_STATUS, compileStatus, 0);
+        var attribute: String?
+        var attrList: String? = ""
+        var uniform: String?
+        val lines = shader.split("\n")
 
-      if (compileStatus[0] != GLES30.GL_TRUE)
+        for (line in lines)
         {
-        String error = GLES30.glGetShaderInfoLog(shaderHandle);
+            if (doAttributes)
+            {
+                attribute = parseOutAttribute(line)
 
-        GLES30.glDeleteShader(shaderHandle);
+                if (attribute != null)
+                {
+                    if (!attrList!!.isEmpty()) attrList += " "
+                    attrList += attribute
+                }
+            }
+
+            uniform = parseOutUniform(line)
 
-        switch (shaderType)
-          {
-          case GLES30.GL_VERTEX_SHADER:   throw new VertexCompilationException(error);
-          case GLES30.GL_FRAGMENT_SHADER: throw new FragmentCompilationException(error);
-          default:                        throw new RuntimeException(error);
-          }
+            if (uniform != null)
+            {
+                if (!mUniList!!.isEmpty()) mUniList += " "
+                mUniList += uniform
+            }
         }
-      }
 
-    return shaderHandle;
+        if (doAttributes)
+        {
+            mAttributeName = attrList!!.split(" ").toTypedArray()
+            mNumAttributes = mAttributeName.size
+        }
     }
 
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private static String insertEnabledEffects(String code, final String effects)
+    ///////////////////////////////////////////////////////////////////////////////////////////////
+    private fun readTextFileFromRawResource(inputStream: InputStream, doAttributes: Boolean): String?
     {
-    final String marker = "// ENABLED EFFECTS WILL BE INSERTED HERE";
-    int length = marker.length();
+        val inputStreamReader = InputStreamReader(inputStream)
+        val bufferedReader = BufferedReader(inputStreamReader)
 
-    int place = code.indexOf(marker);
+        var nextLine: String?
+        var attribute: String?
+        var attrList: String? = ""
+        val body = StringBuilder()
 
-    if( place>=0 )
-      {
-      String begin = code.substring(0,place-1);
-      String end   = code.substring(place+length);
+        try
+        {
+            while ((bufferedReader.readLine().also { nextLine = it }) != null)
+            {
+                body.append(nextLine)
+                body.append('\n')
 
-      return begin + effects + end;
-      }
-    else
-      {
-      DistortedLibrary.logMessage("DistortedProgram: Error: marker string not found in SHADER!");
-      }
+                if (doAttributes)
+                {
+                    attribute = parseOutAttribute(nextLine!!)
 
-    return null;
-    }
+                    if (attribute != null)
+                    {
+                        if (!attrList!!.isEmpty()) attrList += " "
+                        attrList += attribute
+                    }
+                }
+            }
+        }
+        catch (e: IOException) { return null }
 
-///////////////////////////////////////////////////////////////////////////////////////////////////
+        if (doAttributes)
+        {
+            mAttributeName = attrList!!.split(" ").toTypedArray()
+            mNumAttributes = mAttributeName.size
+        }
+
+        return body.toString()
+    }
 
-  private void setUpAttributes()
+    ///////////////////////////////////////////////////////////////////////////////////////////////
+    private fun setUpAttributes()
     {
-    int[] att = new int[mNumAttributes];
+        val att = IntArray(mNumAttributes)
 
-    for(int i=0; i<mNumAttributes; i++)
-      {
-      att[i] = GLES30.glGetAttribLocation( mProgramHandle, mAttributeName[i]);
-      }
+        for (i in 0..<mNumAttributes)
+            att[i] = GLES30.glGetAttribLocation(programHandle, mAttributeName[i])
 
-    int emptyAttrs = 0;
+        var emptyAttrs=0
+        var i=0
 
-    for(int i=0; i<mNumAttributes-emptyAttrs; i++)
-      {
-      if( att[i] < 0 )
+        while (i < mNumAttributes-emptyAttrs)
         {
-        emptyAttrs++;
+            if (att[i] < 0)
+            {
+                emptyAttrs++
 
-        for(int j=i; j<mNumAttributes-emptyAttrs; j++)
-          {
-          att[j] = att[j+1];
-          mAttributeName[j] = mAttributeName[j+1];
-          }
+                for (j in i..<mNumAttributes - emptyAttrs)
+                {
+                    att[j] = att[j+1]
+                    mAttributeName[j] = mAttributeName[j+1]
+                }
+            }
+            i++
         }
-      }
-
-    if( emptyAttrs>0 )
-      {
-      mNumAttributes -= emptyAttrs;
-      mAttribute = new int[mNumAttributes];
-      System.arraycopy(att, 0, mAttribute, 0, mNumAttributes);
-      }
-    else
-      {
-      mAttribute = att;
-      }
-
-    setUpAttributeLayout();
-    }
 
-///////////////////////////////////////////////////////////////////////////////////////////////////
+        if (emptyAttrs > 0)
+        {
+            mNumAttributes -= emptyAttrs
+            mAttribute = IntArray(mNumAttributes)
+            att.copyInto(mAttribute!!, 0, 0, mNumAttributes)
+        }
+        else
+        {
+            mAttribute = att
+        }
+
+        setUpAttributeLayout()
+    }
 
-  private void setUpAttributeLayout()
+    ///////////////////////////////////////////////////////////////////////////////////////////////
+    private fun setUpAttributeLayout()
     {
-    switch(mNumAttributes)
-      {
-      case 4: mAttributeLayout = ATTR_LAYOUT_PNTC;
-              break;
-      case 3: if( mAttributeName[2].equals("a_TexCoordinate") ) mAttributeLayout = ATTR_LAYOUT_PNT;
-              else if( mAttributeName[2].equals("a_Component") )
-                {
-                if( mAttributeName[1].equals("a_TexCoordinate") ) mAttributeLayout = ATTR_LAYOUT_PTC;
-                else if( mAttributeName[1].equals("a_Normal"  ) ) mAttributeLayout = ATTR_LAYOUT_PNC;
-                else
+        when (mNumAttributes)
+        {
+            4 -> mAttributeLayout = ATTR_LAYOUT_PNTC
+
+            3 ->       if (mAttributeName[2] == "a_TexCoordinate")     mAttributeLayout = ATTR_LAYOUT_PNT
+                  else if (mAttributeName[2] == "a_Component")
                   {
-                  mAttributeLayout = ATTR_LAYOUT_UNK;
-                  DistortedLibrary.logMessage("DistortedProgram: 1 Error in attribute layout: "+mAttributeName[1]);
+                           if (mAttributeName[1] == "a_TexCoordinate") mAttributeLayout = ATTR_LAYOUT_PTC
+                      else if (mAttributeName[1] == "a_Normal")        mAttributeLayout = ATTR_LAYOUT_PNC
+                      else
+                      {
+                          mAttributeLayout = ATTR_LAYOUT_UNK
+                          DistortedLibrary.logMessage("DistortedProgram: 1 Error in attribute layout: " + mAttributeName[1])
+                      }
+                  }
+                  else
+                  {
+                      mAttributeLayout = ATTR_LAYOUT_UNK
+                      DistortedLibrary.logMessage("DistortedProgram: 2 Error in attribute layout: " + mAttributeName[2])
                   }
-                }
-              else
-                {
-                mAttributeLayout = ATTR_LAYOUT_UNK;
-                DistortedLibrary.logMessage("DistortedProgram: 2 Error in attribute layout: "+mAttributeName[2]);
-                }
-              break;
-      case 2: if( mAttributeName[1].equals("a_TexCoordinate") ) mAttributeLayout = ATTR_LAYOUT_PT;
-              else
-                {
-                mAttributeLayout = ATTR_LAYOUT_UNK;
-                DistortedLibrary.logMessage("DistortedProgram: 3 Error in attribute layout: "+mAttributeName[1]);
-                }
-              break;
-      case 1: if( mAttributeName[0].equals("a_Position") ) mAttributeLayout = ATTR_LAYOUT_P;
-              else
-                {
-                mAttributeLayout = ATTR_LAYOUT_UNK;
-                DistortedLibrary.logMessage("DistortedProgram: 4 Error in attribute layout: "+mAttributeName[0]);
-                }
-              break;
-      default:mAttributeLayout = ATTR_LAYOUT_UNK;
-              DistortedLibrary.logMessage("DistortedProgram: 5 Error in attribute layout: "+mNumAttributes);
-      }
-    }
 
-///////////////////////////////////////////////////////////////////////////////////////////////////
+            2 -> if (mAttributeName[1] == "a_TexCoordinate") mAttributeLayout = ATTR_LAYOUT_PT
+                 else
+                 {
+                     mAttributeLayout = ATTR_LAYOUT_UNK
+                     DistortedLibrary.logMessage("DistortedProgram: 3 Error in attribute layout: " + mAttributeName[1])
+                 }
+
+            1 -> if (mAttributeName[0] == "a_Position") mAttributeLayout = ATTR_LAYOUT_P
+                 else
+                 {
+                     mAttributeLayout = ATTR_LAYOUT_UNK
+                     DistortedLibrary.logMessage("DistortedProgram: 4 Error in attribute layout: " + mAttributeName[0])
+                 }
+
+            else ->
+                 {
+                     mAttributeLayout = ATTR_LAYOUT_UNK
+                     DistortedLibrary.logMessage("DistortedProgram: 5 Error in attribute layout: $mNumAttributes")
+                 }
+        }
+    }
 
-  private void setUpUniforms()
+    ///////////////////////////////////////////////////////////////////////////////////////////////
+    private fun setUpUniforms()
     {
-    if( mNumUniforms>0 )
-      {
-      mUniform = new int[mNumUniforms];
-      String[] uniformName = mUniList.split(" ");
-
-      for(int i=0; i<mNumUniforms; i++)
+        if (mNumUniforms>0)
         {
-        mUniform[i] = GLES30.glGetUniformLocation( mProgramHandle, uniformName[i]);
+            mUniform = IntArray(mNumUniforms)
+            val uniformName = mUniList!!.split(" ".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray()
+
+            for (i in 0..<mNumUniforms)
+                mUniform!![i] = GLES30.glGetUniformLocation(programHandle, uniformName[i])
         }
-      }
-    else mUniform = null;
+        else mUniform = null
     }
 
-///////////////////////////////////////////////////////////////////////////////////////////////////
-/**
- * Only for use by the library itself.
- *
- * @y.exclude
- */
-  public DistortedProgram(final InputStream vert, final InputStream frag, final String vertHeader, final String fragHeader,
-                          int glslVersion, final String[] feedback )
-  throws FragmentCompilationException,VertexCompilationException,LinkingException
+    ///////////////////////////////////////////////////////////////////////////////////////////////
+    /** Only for use by the library itself.
+    *
+    * @y.exclude
+    */
+    constructor(vert: InputStream, frag: InputStream, vertHeader: String,
+                fragHeader: String, glslVersion: Int, feedback: Array<String?>?)
     {
-    init(glslVersion);
+        init(glslVersion)
 
-    final String vertShader = readTextFileFromRawResource(vert, true );
-    final String fragShader = readTextFileFromRawResource(frag, false);
+        val vertShader = readTextFileFromRawResource(vert, true)
+        val fragShader = readTextFileFromRawResource(frag, false)
 
-    final int vertShaderHandle = compileShader(GLES30.GL_VERTEX_SHADER  , vertHeader + vertShader);
-    final int fragShaderHandle = compileShader(GLES30.GL_FRAGMENT_SHADER, fragHeader + fragShader);
+        val vertShaderHandle = compileShader(GLES30.GL_VERTEX_SHADER  , vertHeader + vertShader)
+        val fragShaderHandle = compileShader(GLES30.GL_FRAGMENT_SHADER, fragHeader + fragShader)
 
-    mProgramHandle = createAndLinkProgram(vertShaderHandle, fragShaderHandle, mAttributeName, glslVersion>= 300 ? feedback:null );
+        programHandle = createAndLinkProgram(
+            vertShaderHandle,
+            fragShaderHandle,
+            mAttributeName,
+            if (glslVersion >= 300) feedback else null
+        )
 
-    setUpAttributes();
-    setUpUniforms();
+        setUpAttributes()
+        setUpUniforms()
     }
 
-///////////////////////////////////////////////////////////////////////////////////////////////////
-/**
- * Only for use by the library itself.
- *
- * @y.exclude
- */
-  public DistortedProgram(final InputStream vert, final InputStream frag, final String vertHeader, final String fragHeader,
-                          final String enabledVert, final String enabledFrag, int glslVersion, final String[] feedback )
-  throws FragmentCompilationException,VertexCompilationException,LinkingException
+    ///////////////////////////////////////////////////////////////////////////////////////////////
+    /** Only for use by the library itself.
+    *
+    * @y.exclude
+    */
+    constructor(vert: InputStream, frag: InputStream, vertHeader: String, fragHeader: String,
+                enabledVert: String?, enabledFrag: String?, glslVersion: Int, feedback: Array<String?>?)
     {
-    init(glslVersion);
+        init(glslVersion)
 
-    String vertShader = readTextFileFromRawResource( vert, true );
-    String fragShader = readTextFileFromRawResource( frag, false);
+        var vertShader = readTextFileFromRawResource(vert, true)
+        var fragShader = readTextFileFromRawResource(frag, false)
 
-    if( enabledVert!=null ) vertShader = insertEnabledEffects(vertShader,enabledVert);
-    if( enabledFrag!=null ) fragShader = insertEnabledEffects(fragShader,enabledFrag);
+        if (enabledVert != null) vertShader = insertEnabledEffects(vertShader!!, enabledVert)
+        if (enabledFrag != null) fragShader = insertEnabledEffects(fragShader!!, enabledFrag)
 
-    final int vertShaderHandle = compileShader(GLES30.GL_VERTEX_SHADER  , vertHeader + vertShader);
-    final int fragShaderHandle = compileShader(GLES30.GL_FRAGMENT_SHADER, fragHeader + fragShader);
+        val vertShaderHandle = compileShader(GLES30.GL_VERTEX_SHADER  , vertHeader + vertShader)
+        val fragShaderHandle = compileShader(GLES30.GL_FRAGMENT_SHADER, fragHeader + fragShader)
 
-    mProgramHandle = createAndLinkProgram(vertShaderHandle, fragShaderHandle, mAttributeName, glslVersion>= 300 ? feedback:null );
+        programHandle = createAndLinkProgram(
+            vertShaderHandle,
+            fragShaderHandle,
+            mAttributeName,
+            if (glslVersion >= 300) feedback else null
+        )
 
-    setUpAttributes();
-    setUpUniforms();
+        setUpAttributes()
+        setUpUniforms()
     }
 
-///////////////////////////////////////////////////////////////////////////////////////////////////
-/**
- * Only for use by the library itself.
- *
- * @y.exclude
- */
-  public DistortedProgram(final InputStream vertex, final InputStream fragment, final String vertexHeader, final String fragmentHeader, int glslVersion )
-  throws FragmentCompilationException,VertexCompilationException,LinkingException
+    ///////////////////////////////////////////////////////////////////////////////////////////////
+    /** Only for use by the library itself.
+    *
+    * @y.exclude
+    */
+    constructor( vert: InputStream, frag: InputStream, vertHeader: String, fragHeader: String, glslVersion: Int) :
+            this(vert, frag, vertHeader, fragHeader, glslVersion, null)
+
+    ///////////////////////////////////////////////////////////////////////////////////////////////
+    // PUBLIC API
+    /** Create a new Shader Program from two source strings.
+    *
+    * Needs to be called from a thread holding the OpenGL context.
+    *
+    * @param vert Vertex shader code.
+    * @param frag Fragment shader code.
+    * @throws FragmentCompilationException fragment shader failed to compile
+    * @throws VertexCompilationException vertex shader failed to compile
+    * @throws LinkingException shaders failed to link
+    */
+    constructor(vert: String, frag: String)
     {
-    this(vertex,fragment,vertexHeader,fragmentHeader,glslVersion,null);
-    }
+        init(300)
 
-///////////////////////////////////////////////////////////////////////////////////////////////////
-// PUBLIC API
-///////////////////////////////////////////////////////////////////////////////////////////////////
-/**
- * Create a new Shader Program from two source strings.
- * <p>
- * Needs to be called from a thread holding the OpenGL context.
- *
- * @param vertex   Vertex shader code.
- * @param fragment Fragment shader code.
- * @throws FragmentCompilationException fragment shader failed to compile
- * @throws VertexCompilationException vertex shader failed to compile
- * @throws LinkingException shaders failed to link
- */
-  public DistortedProgram(final String vertex, final String fragment)
-  throws FragmentCompilationException,VertexCompilationException,LinkingException
-    {
-    init(300);
+        doAttributes(vert, true)
+        doAttributes(frag, false)
 
-    doAttributes(vertex  , true );
-    doAttributes(fragment, false);
+        val vertHandle = compileShader(GLES30.GL_VERTEX_SHADER  , vert)
+        val fragHandle = compileShader(GLES30.GL_FRAGMENT_SHADER, frag)
 
-    final int vertexShaderHandle   = compileShader(GLES30.GL_VERTEX_SHADER  , vertex  );
-    final int fragmentShaderHandle = compileShader(GLES30.GL_FRAGMENT_SHADER, fragment);
+        programHandle = createAndLinkProgram(vertHandle, fragHandle, mAttributeName, null)
 
-    mProgramHandle = createAndLinkProgram(vertexShaderHandle, fragmentShaderHandle, mAttributeName, null );
-
-    setUpAttributes();
-    setUpUniforms();
+        setUpAttributes()
+        setUpUniforms()
     }
 
-///////////////////////////////////////////////////////////////////////////////////////////////////
-/**
- * Return the handle of the created program so that we can later, say, call glUseProgram.
- */
-  public int getProgramHandle()
+    ///////////////////////////////////////////////////////////////////////////////////////////////
+    /** Return the handle of the created program so that we can later, say, call glUseProgram.
+    *
+    * Use the program and enable all vertex attribute arrays.
+    * Needs to be called from a thread holding the OpenGL context.
+    */
+    fun useProgram()
     {
-    return mProgramHandle;
+        GLES30.glUseProgram(programHandle)
+
+        for (i in 0..<mNumAttributes)
+            GLES30.glEnableVertexAttribArray(mAttribute!![i])
     }
 
-///////////////////////////////////////////////////////////////////////////////////////////////////
-/**
- * Use the program and enable all vertex attribute arrays.
- * Needs to be called from a thread holding the OpenGL context.
- */
-  public void useProgram()
+    ///////////////////////////////////////////////////////////////////////////////////////////////
+    /** Disable all vertex attribute arrays.
+    * Needs to be called from a thread holding the OpenGL context.
+    */
+    fun stopUsingProgram()
     {
-    GLES30.glUseProgram(mProgramHandle);
+        GLES30.glUseProgram(0)
 
-    for(int i=0; i<mNumAttributes; i++)
-      {
-      GLES30.glEnableVertexAttribArray(mAttribute[i]);
-      }
+        for (i in 0..<mNumAttributes)
+            GLES30.glDisableVertexAttribArray(mAttribute!![i])
     }
 
-///////////////////////////////////////////////////////////////////////////////////////////////////
-/**
- * Disable all vertex attribute arrays.
- * Needs to be called from a thread holding the OpenGL context.
- */
-  public void stopUsingProgram()
+    companion object
     {
-    GLES30.glUseProgram(0);
+        const val ATTR_LAYOUT_PNTC: Int = 0
+        const val ATTR_LAYOUT_PTC : Int = 1
+        const val ATTR_LAYOUT_PNT : Int = 2
+        const val ATTR_LAYOUT_PNC : Int = 3
+        const val ATTR_LAYOUT_PT  : Int = 4
+        const val ATTR_LAYOUT_P   : Int = 5
+        const val ATTR_LAYOUT_UNK : Int = 6
+
+        ///////////////////////////////////////////////////////////////////////////////////////////
+        @Throws(FragmentCompilationException::class, VertexCompilationException::class)
+        private fun compileShader(shaderType: Int, shaderSource: String): Int
+        {
+            val shaderHandle = GLES30.glCreateShader(shaderType)
 
-    for(int i=0; i<mNumAttributes; i++)
-      {
-      GLES30.glDisableVertexAttribArray(mAttribute[i]);
-      }
+            if (shaderHandle != 0)
+            {
+                GLES30.glShaderSource(shaderHandle, shaderSource)
+                GLES30.glCompileShader(shaderHandle)
+                val compileStatus = IntArray(1)
+                GLES30.glGetShaderiv(shaderHandle, GLES30.GL_COMPILE_STATUS, compileStatus, 0)
+
+                if (compileStatus[0] != GLES30.GL_TRUE)
+                {
+                    val error = GLES30.glGetShaderInfoLog(shaderHandle)
+
+                    GLES30.glDeleteShader(shaderHandle)
+
+                    when (shaderType)
+                    {
+                        GLES30.GL_VERTEX_SHADER   -> throw VertexCompilationException(error)
+                        GLES30.GL_FRAGMENT_SHADER -> throw FragmentCompilationException(error)
+                        else                      -> throw RuntimeException(error)
+                    }
+                }
+            }
+
+            return shaderHandle
+        }
+
+        ///////////////////////////////////////////////////////////////////////////////////////////
+        private fun insertEnabledEffects(code: String, effects: String): String?
+        {
+            val marker = "// ENABLED EFFECTS WILL BE INSERTED HERE"
+            val length = marker.length
+            val place = code.indexOf(marker)
+
+            if (place >= 0)
+            {
+                val beg = code.substring(0, place-1)
+                val end = code.substring(place+length)
+                return beg+effects+end
+            }
+            else DistortedLibrary.logMessage("DistortedProgram: Error: marker string not found in SHADER!")
+
+            return null
+        }
     }
-  }
+}
 
 
diff --git a/src/main/java/org/distorted/library/program/FragmentCompilationException.kt b/src/main/java/org/distorted/library/program/FragmentCompilationException.kt
index 48e1cfc..7293c9f 100644
--- a/src/main/java/org/distorted/library/program/FragmentCompilationException.kt
+++ b/src/main/java/org/distorted/library/program/FragmentCompilationException.kt
@@ -18,64 +18,36 @@
 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA                //
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-package org.distorted.library.program;
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-/**
- *  Thrown asynchronously by the library whenever shader compilation fails.
- *  If compilation of the fragment shader fails for some other reason than too many uniforms.
- *  <p>
- *  This can happen on older OpenGL ES 2.0 devices if they, say, do not support variable loops in the shaders.
- *  Theoretically should never happen on devices supporting at least OpenGL ES 3.0.
- */
-
-@SuppressWarnings("serial")
-public class FragmentCompilationException extends Exception 
-  {
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-/**
- * Default empty constructor  
- */
-  public FragmentCompilationException() 
-    {
-   
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-/**
- * Constructor with a message describing why compilation failed.  
- *   
- * @param detailMessage Message describing why compilation failed
- */
-  public FragmentCompilationException(String detailMessage) 
-    {
-    super(detailMessage);
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-/**
- * Constructor necessary to make Chained Exceptions working.
- *  
- * @param throwable The parent Throwable.
- */
-  public FragmentCompilationException(Throwable throwable) 
-    {
-    super(throwable);
-    }
+package org.distorted.library.program
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 /**
- * Constructor necessary to make Chained Exceptions working.
- *   
- * @param detailMessage Message describing why compilation failed
- * @param throwable The parent Throwable.
+ * Thrown asynchronously by the library whenever shader compilation fails.
+ * If compilation of the fragment shader fails for some other reason than too many uniforms.
+ *
+ * This can happen on older OpenGL ES 2.0 devices if they, say, do not support variable loops in the shaders.
+ * Theoretically should never happen on devices supporting at least OpenGL ES 3.0.
  */
-  public FragmentCompilationException(String detailMessage, Throwable throwable) 
-    {
-    super(detailMessage, throwable);
-    }
 
-///////////////////////////////////////////////////////////////////////////////////////////////////  
-  }
+class FragmentCompilationException : Exception
+{
+    /**
+     * @param detailMessage Message describing why compilation failed
+     */
+    constructor(detailMessage: String?) : super(detailMessage)
+
+    ///////////////////////////////////////////////////////////////////////////////////////////////
+    /** Constructor necessary to make Chained Exceptions working.
+     *
+     * @param throwable The parent Throwable.
+     */
+    constructor(throwable: Throwable?) : super(throwable)
+
+    ///////////////////////////////////////////////////////////////////////////////////////////////
+    /** Constructor necessary to make Chained Exceptions working.
+     *
+     * @param detailMessage Message describing why compilation failed
+     * @param throwable The parent Throwable.
+     */
+    constructor(detailMessage: String?, throwable: Throwable?) : super(detailMessage, throwable)
+}
diff --git a/src/main/java/org/distorted/library/program/FragmentUniformsException.kt b/src/main/java/org/distorted/library/program/FragmentUniformsException.kt
index fa097b4..c034b6b 100644
--- a/src/main/java/org/distorted/library/program/FragmentUniformsException.kt
+++ b/src/main/java/org/distorted/library/program/FragmentUniformsException.kt
@@ -18,91 +18,50 @@
 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA                //
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-package org.distorted.library.program;
+package org.distorted.library.program
 
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-import org.distorted.library.main.DistortedLibrary;
-
-/**
- *  Thrown asynchronously by the library whenever shader compilation fails.
- *  If compilation of the fragment shader fails because of too many uniforms there, i.e. because
- *  we have set {@link DistortedLibrary#setMax(org.distorted.library.effect.EffectType, int)}
- *  to too high value.
- */
+import org.distorted.library.main.DistortedLibrary
 
-@SuppressWarnings("serial")
-public class FragmentUniformsException extends Exception 
-  {
-  private int max=0;
-    
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 /**
- * Default empty constructor  
- */   
-  public FragmentUniformsException() 
-    {
-   
-    }
+ * Thrown asynchronously by the library whenever shader compilation fails.
+ * If compilation of the fragment shader fails because of too many uniforms there, i.e. because
+ * we have set [DistortedLibrary.setMax]
+ * to too high value.
+ */
 
-///////////////////////////////////////////////////////////////////////////////////////////////////
-/**
- * Constructor with a message describing why compilation failed.  
- *   
- * @param detailMessage Message describing why compilation failed
- */  
-  public FragmentUniformsException(String detailMessage) 
-    {
-    super(detailMessage);
-    }
+class FragmentUniformsException : Exception
+{
+    var max: Int = 0
+        private set
 
-///////////////////////////////////////////////////////////////////////////////////////////////////
-/**
- * Constructor necessary to make Chained Exceptions working.
- *  
- * @param throwable The parent Throwable.
- */ 
-  public FragmentUniformsException(Throwable throwable) 
-    {
-    super(throwable);
-    }
+    ///////////////////////////////////////////////////////////////////////////////////////////////
+    /**
+    * @param detailMessage Message describing why compilation failed
+    */
+    constructor(detailMessage: String?) : super(detailMessage)
 
-///////////////////////////////////////////////////////////////////////////////////////////////////
-/**
- * Constructor necessary to make Chained Exceptions working.
- *   
- * @param detailMessage Message describing why compilation failed
- * @param throwable The parent Throwable.
- */  
-  public FragmentUniformsException(String detailMessage, Throwable throwable) 
-    {
-    super(detailMessage, throwable);
-    }
+    ///////////////////////////////////////////////////////////////////////////////////////////////
+    /** Constructor necessary to make Chained Exceptions working.
+    *
+    * @param throwable The parent Throwable.
+    */
+    constructor(throwable: Throwable?) : super(throwable)
 
-///////////////////////////////////////////////////////////////////////////////////////////////////
-/**
- * Constructor with a message describing why compilation failed and integer holding the maximum
- * number of uniforms in Fragment Shader supported by current hardware.   
- *   
- * @param detailMessage Message describing why compilation failed
- * @param m maximum number of uniforms in Fragment Shader supported by current hardware.   
- */   
-  public FragmentUniformsException(String detailMessage, int m) 
-    {
-    super(detailMessage);
-    max = m;
-    }
+    ///////////////////////////////////////////////////////////////////////////////////////////////
+    /** Constructor necessary to make Chained Exceptions working.
+    *
+    * @param detailMessage Message describing why compilation failed
+    * @param throwable The parent Throwable.
+    */
+    constructor(detailMessage: String?, throwable: Throwable?) : super(detailMessage, throwable)
 
-///////////////////////////////////////////////////////////////////////////////////////////////////  
-/**
- * Gets the maximum number of uniforms in fragment shader supported by current hardware.
- * 
- * @return Maximum number of uniforms in fragment shader supported by current hardware.   
- */
-  public int getMax()
-    {
-    return max;  
-    }
-  
-///////////////////////////////////////////////////////////////////////////////////////////////////  
-  }
+    ///////////////////////////////////////////////////////////////////////////////////////////////
+    /** Constructor with a message describing why compilation failed and integer holding the maximum
+    * number of uniforms in Fragment Shader supported by current hardware.
+    *
+    * @param detailMessage Message describing why compilation failed
+    * @param m maximum number of uniforms in Fragment Shader supported by current hardware.
+    */
+    constructor(detailMessage: String?, m: Int) : super(detailMessage) { max = m }
+}
diff --git a/src/main/java/org/distorted/library/program/LinkingException.kt b/src/main/java/org/distorted/library/program/LinkingException.kt
index 1305ee3..16e5dc8 100644
--- a/src/main/java/org/distorted/library/program/LinkingException.kt
+++ b/src/main/java/org/distorted/library/program/LinkingException.kt
@@ -18,64 +18,35 @@
 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA                //
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-package org.distorted.library.program;
+package org.distorted.library.program
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
-
-import org.distorted.library.main.DistortedLibrary;
-
 /**
- *  Thrown asynchronously by the library whenever shader compilation fails.
- *  If linking of the Shaders fails.
- *  <p>
- *  Theoretically this should never happen.
+ * Thrown asynchronously by the library whenever shader compilation fails.
+ * If linking of the Shaders fails.
+ *
+ * Theoretically this should never happen.
  */
-@SuppressWarnings("serial")
-public class LinkingException extends Exception 
-  {
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-/**
- * Default empty constructor  
- */      
-  public LinkingException() 
-    {
-   
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-/**
- * Constructor with a message describing why linking failed.  
- *   
- * @param detailMessage Message describing why linking failed
- */    
-  public LinkingException(String detailMessage) 
-    {
-    super(detailMessage);
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-/**
- * Constructor necessary to make Chained Exceptions working.
- *  
- * @param throwable The parent Throwable.
- */  
-  public LinkingException(Throwable throwable) 
-    {
-    super(throwable);
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-/**
- * Constructor necessary to make Chained Exceptions working.
- *   
- * @param detailMessage Message describing why linking failed
- * @param throwable The parent Throwable.
- */      
-  public LinkingException(String detailMessage, Throwable throwable) 
-    {
-    super(detailMessage, throwable);
-    }
 
-///////////////////////////////////////////////////////////////////////////////////////////////////  
-  }
+class LinkingException : Exception
+{
+    /**
+     * @param detailMessage Message describing why linking failed
+     */
+    constructor(detailMessage: String?) : super(detailMessage)
+
+    ///////////////////////////////////////////////////////////////////////////////////////////////
+    /** Constructor necessary to make Chained Exceptions working.
+     *
+     * @param throwable The parent Throwable.
+     */
+    constructor(throwable: Throwable?) : super(throwable)
+
+    ///////////////////////////////////////////////////////////////////////////////////////////////
+    /** Constructor necessary to make Chained Exceptions working.
+     *
+     * @param detailMessage Message describing why linking failed
+     * @param throwable The parent Throwable.
+     */
+    constructor(detailMessage: String?, throwable: Throwable?) : super(detailMessage, throwable)
+}
diff --git a/src/main/java/org/distorted/library/program/VertexCompilationException.kt b/src/main/java/org/distorted/library/program/VertexCompilationException.kt
index 5756f94..cdf18b1 100644
--- a/src/main/java/org/distorted/library/program/VertexCompilationException.kt
+++ b/src/main/java/org/distorted/library/program/VertexCompilationException.kt
@@ -18,64 +18,36 @@
 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA                //
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-package org.distorted.library.program;
+package org.distorted.library.program
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
-
 /**
- *  Thrown asynchronously by the library whenever shader compilation fails.
- *  If compilation of the vertex shader fails for some other reason than too many uniforms.
- *  <p>
- *  This can happen on older OpenGL ES 2.0 devices if they, say, do not support variable loops in the shaders.
- *  Theoretically should never happen on devices supporting at least OpenGL ES 3.0.
+ * Thrown asynchronously by the library whenever shader compilation fails.
+ * If compilation of the vertex shader fails for some other reason than too many uniforms.
+ *
+ * This can happen on older OpenGL ES 2.0 devices if they, say, do not support variable loops in
+ * the shaders. Theoretically should never happen on devices supporting at least OpenGL ES 3.0.
  */
 
-@SuppressWarnings("serial")
-public class VertexCompilationException extends Exception 
-  {
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-/**
- * Default empty constructor  
- */   
-  public VertexCompilationException() 
-    {
-   
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-/**
- * Constructor with a message describing why compilation failed.  
- *   
- * @param detailMessage Message describing why compilation failed
- */  
-  public VertexCompilationException(String detailMessage) 
-    {
-    super(detailMessage);
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-/**
- * Constructor necessary to make Chained Exceptions working.
- *  
- * @param throwable The parent Throwable.
- */ 
-  public VertexCompilationException(Throwable throwable) 
-    {
-    super(throwable);
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-/**
- * Constructor necessary to make Chained Exceptions working.
- *   
- * @param detailMessage Message describing why compilation failed
- * @param throwable The parent Throwable.
- */  
-  public VertexCompilationException(String detailMessage, Throwable throwable) 
-    {
-    super(detailMessage, throwable);
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////  
-  }
+class VertexCompilationException : Exception
+{
+    /**
+    * @param detailMessage Message describing why compilation failed
+    */
+    constructor(detailMessage: String?) : super(detailMessage)
+
+    ///////////////////////////////////////////////////////////////////////////////////////////////
+    /** Constructor necessary to make Chained Exceptions working.
+    *
+    * @param throwable The parent Throwable.
+    */
+    constructor(throwable: Throwable?) : super(throwable)
+
+    ///////////////////////////////////////////////////////////////////////////////////////////////
+    /** Constructor necessary to make Chained Exceptions working.
+    *
+    * @param detailMessage Message describing why compilation failed
+    * @param throwable The parent Throwable.
+    */
+    constructor(detailMessage: String?, throwable: Throwable?) : super( detailMessage, throwable)
+}
diff --git a/src/main/java/org/distorted/library/program/VertexUniformsException.kt b/src/main/java/org/distorted/library/program/VertexUniformsException.kt
index 0833a01..5fbd69f 100644
--- a/src/main/java/org/distorted/library/program/VertexUniformsException.kt
+++ b/src/main/java/org/distorted/library/program/VertexUniformsException.kt
@@ -18,91 +18,51 @@
 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA                //
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-package org.distorted.library.program;
+package org.distorted.library.program
 
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-import org.distorted.library.main.DistortedLibrary;
-
-/**
- *  Thrown asynchronously by the library whenever shader compilation fails.
- *  If compilation of the Vertex Shader fails because of too many uniforms there, i.e. because
- *  we have set {@link DistortedLibrary#setMax(org.distorted.library.effect.EffectType, int)}
- *  to too high value.
- */
+import org.distorted.library.main.DistortedLibrary
 
-@SuppressWarnings("serial")
-public class VertexUniformsException extends Exception 
-  {
-  private int max=0;
-  
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 /**
- * Default empty constructor  
- */      
-  public VertexUniformsException() 
-    {
-   
-    }
+ * Thrown asynchronously by the library whenever shader compilation fails.
+ * If compilation of the Vertex Shader fails because of too many uniforms there, i.e. because
+ * we have set [DistortedLibrary.setMax]
+ * to too high value.
+ */
 
-///////////////////////////////////////////////////////////////////////////////////////////////////
-/**
- * Constructor with a message describing why compilation failed.  
- *   
- * @param detailMessage Message describing why compilation failed
- */   
-  public VertexUniformsException(String detailMessage) 
-    {
-    super(detailMessage);
-    }
+class VertexUniformsException : Exception
+{
+    var max: Int = 0
+        private set
 
-///////////////////////////////////////////////////////////////////////////////////////////////////
-/**
- * Constructor necessary to make Chained Exceptions working.
- *  
- * @param throwable The parent Throwable.
- */ 
-  public VertexUniformsException(Throwable throwable) 
-    {
-    super(throwable);
-    }
+    ///////////////////////////////////////////////////////////////////////////////////////////////
+    /** Constructor with a message describing why compilation failed.
+    *
+    * @param detailMessage Message describing why compilation failed
+    */
+    constructor(detailMessage: String?) : super(detailMessage)
 
-///////////////////////////////////////////////////////////////////////////////////////////////////
-/**
- * Constructor necessary to make Chained Exceptions working.
- *   
- * @param detailMessage Message describing why compilation failed
- * @param throwable The parent Throwable.
- */    
-  public VertexUniformsException(String detailMessage, Throwable throwable) 
-    {
-    super(detailMessage, throwable);
-    }
+    ///////////////////////////////////////////////////////////////////////////////////////////////
+    /** Constructor necessary to make Chained Exceptions working.
+    *
+    * @param throwable The parent Throwable.
+    */
+    constructor(throwable: Throwable?) : super(throwable)
 
-///////////////////////////////////////////////////////////////////////////////////////////////////
-/**
- * Constructor with a message describing why compilation failed and integer holding the maximum
- * number of uniforms in Vertex Shader supported by current hardware.   
- *   
- * @param detailMessage Message describing why compilation failed
- * @param m maximum number of uniforms in Vertex Shader supported by current hardware.   
- */     
-  public VertexUniformsException(String detailMessage, int m) 
-    {
-    super(detailMessage);
-    max = m;
-    }
+    ///////////////////////////////////////////////////////////////////////////////////////////////
+    /** Constructor necessary to make Chained Exceptions working.
+    *
+    * @param detailMessage Message describing why compilation failed
+    * @param throwable The parent Throwable.
+    */
+    constructor(detailMessage: String?, throwable: Throwable?) : super(detailMessage, throwable)
 
-///////////////////////////////////////////////////////////////////////////////////////////////////  
-/**
- * Gets the maximum number of uniforms in Vertex Shader supported by current hardware.
- * 
- * @return Maximum number of uniforms in Vertex Shader supported by current hardware.   
- */
-  public int getMax()
-    {
-    return max;  
-    }
-  
-///////////////////////////////////////////////////////////////////////////////////////////////////  
-  }
+    ///////////////////////////////////////////////////////////////////////////////////////////////
+    /** Constructor with a message describing why compilation failed and integer holding the maximum
+    * number of uniforms in Vertex Shader supported by current hardware.
+    *
+    * @param detailMessage Message describing why compilation failed
+    * @param m maximum number of uniforms in Vertex Shader supported by current hardware.
+    */
+    constructor(detailMessage: String?, m: Int) : super(detailMessage) { max = m }
+}
