@ -0,0 +1,15 @@
|
|||||||
|
*.iml
|
||||||
|
.gradle
|
||||||
|
/local.properties
|
||||||
|
/.idea/caches
|
||||||
|
/.idea/libraries
|
||||||
|
/.idea/modules.xml
|
||||||
|
/.idea/workspace.xml
|
||||||
|
/.idea/navEditor.xml
|
||||||
|
/.idea/assetWizardSettings.xml
|
||||||
|
.DS_Store
|
||||||
|
/build
|
||||||
|
/captures
|
||||||
|
.externalNativeBuild
|
||||||
|
.cxx
|
||||||
|
local.properties
|
@ -0,0 +1,3 @@
|
|||||||
|
# Default ignored files
|
||||||
|
/shelf/
|
||||||
|
/workspace.xml
|
@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="CompilerConfiguration">
|
||||||
|
<bytecodeTargetLevel target="11" />
|
||||||
|
</component>
|
||||||
|
</project>
|
@ -0,0 +1,17 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="deploymentTargetDropDown">
|
||||||
|
<targetSelectedWithDropDown>
|
||||||
|
<Target>
|
||||||
|
<type value="QUICK_BOOT_TARGET" />
|
||||||
|
<deviceKey>
|
||||||
|
<Key>
|
||||||
|
<type value="VIRTUAL_DEVICE_PATH" />
|
||||||
|
<value value="$USER_HOME$/.android/avd/Pixel_2_API_29.avd" />
|
||||||
|
</Key>
|
||||||
|
</deviceKey>
|
||||||
|
</Target>
|
||||||
|
</targetSelectedWithDropDown>
|
||||||
|
<timeTargetWasSelectedWithDropDown value="2023-02-11T02:46:29.166859Z" />
|
||||||
|
</component>
|
||||||
|
</project>
|
@ -0,0 +1,20 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="GradleMigrationSettings" migrationVersion="1" />
|
||||||
|
<component name="GradleSettings">
|
||||||
|
<option name="linkedExternalProjectsSettings">
|
||||||
|
<GradleProjectSettings>
|
||||||
|
<option name="testRunner" value="GRADLE" />
|
||||||
|
<option name="distributionType" value="DEFAULT_WRAPPED" />
|
||||||
|
<option name="externalProjectPath" value="$PROJECT_DIR$" />
|
||||||
|
<option name="gradleHome" value="$USER_HOME$/gradle" />
|
||||||
|
<option name="modules">
|
||||||
|
<set>
|
||||||
|
<option value="$PROJECT_DIR$" />
|
||||||
|
<option value="$PROJECT_DIR$/app" />
|
||||||
|
</set>
|
||||||
|
</option>
|
||||||
|
</GradleProjectSettings>
|
||||||
|
</option>
|
||||||
|
</component>
|
||||||
|
</project>
|
@ -0,0 +1,34 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="DesignSurface">
|
||||||
|
<option name="filePathToZoomLevelMap">
|
||||||
|
<map>
|
||||||
|
<entry key="app/src/main/res/drawable/app_background.xml" value="0.1" />
|
||||||
|
<entry key="app/src/main/res/drawable/blue_card.xml" value="0.297" />
|
||||||
|
<entry key="app/src/main/res/drawable/ic_launcher_background.xml" value="0.2285" />
|
||||||
|
<entry key="app/src/main/res/drawable/red_card.xml" value="0.158" />
|
||||||
|
<entry key="app/src/main/res/drawable/stop.xml" value="0.158" />
|
||||||
|
<entry key="app/src/main/res/layout/activity_distance.xml" value="0.22552083333333334" />
|
||||||
|
<entry key="app/src/main/res/layout/activity_frame.xml" value="0.33" />
|
||||||
|
<entry key="app/src/main/res/layout/activity_grid.xml" value="0.3375" />
|
||||||
|
<entry key="app/src/main/res/layout/activity_image_switcher.xml" value="0.22" />
|
||||||
|
<entry key="app/src/main/res/layout/activity_main.xml" value="0.19172113289760348" />
|
||||||
|
<entry key="app/src/main/res/layout/activity_main_screen.xml" value="0.22552083333333334" />
|
||||||
|
<entry key="app/src/main/res/layout/activity_open_glactivity.xml" value="0.30625" />
|
||||||
|
<entry key="app/src/main/res/layout/activity_relative.xml" value="0.1" />
|
||||||
|
<entry key="app/src/main/res/layout/activity_scroll.xml" value="0.16508795669824086" />
|
||||||
|
<entry key="app/src/main/res/layout/activity_table.xml" value="0.24719101123595505" />
|
||||||
|
<entry key="app/src/main/res/layout/content_main_screen.xml" value="0.22552083333333334" />
|
||||||
|
<entry key="app/src/main/res/layout/stop.xml" value="0.32760416666666664" />
|
||||||
|
<entry key="app/src/main/res/layout/test.xml" value="0.41510416666666666" />
|
||||||
|
<entry key="app/src/main/res/menu/menu_main_screen.xml" value="0.221875" />
|
||||||
|
</map>
|
||||||
|
</option>
|
||||||
|
</component>
|
||||||
|
<component name="ProjectRootManager" version="2" languageLevel="JDK_11" default="true" project-jdk-name="Android Studio default JDK" project-jdk-type="JavaSDK">
|
||||||
|
<output url="file://$PROJECT_DIR$/build/classes" />
|
||||||
|
</component>
|
||||||
|
<component name="ProjectType">
|
||||||
|
<option name="id" value="Android" />
|
||||||
|
</component>
|
||||||
|
</project>
|
@ -0,0 +1 @@
|
|||||||
|
/build
|
@ -0,0 +1,53 @@
|
|||||||
|
plugins {
|
||||||
|
id 'com.android.application'
|
||||||
|
id 'org.jetbrains.kotlin.android'
|
||||||
|
id 'kotlin-android-extensions'
|
||||||
|
}
|
||||||
|
|
||||||
|
android {
|
||||||
|
compileSdk 33
|
||||||
|
|
||||||
|
defaultConfig {
|
||||||
|
applicationId "sgd.and04.layout"
|
||||||
|
minSdk 27
|
||||||
|
targetSdk 32
|
||||||
|
versionCode 1
|
||||||
|
versionName "1.0"
|
||||||
|
|
||||||
|
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
||||||
|
}
|
||||||
|
|
||||||
|
buildTypes {
|
||||||
|
release {
|
||||||
|
minifyEnabled false
|
||||||
|
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
compileOptions {
|
||||||
|
sourceCompatibility JavaVersion.VERSION_1_8
|
||||||
|
targetCompatibility JavaVersion.VERSION_1_8
|
||||||
|
}
|
||||||
|
kotlinOptions {
|
||||||
|
jvmTarget = '1.8'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
|
||||||
|
implementation 'androidx.core:core-ktx:1.7.0'
|
||||||
|
implementation 'androidx.appcompat:appcompat:1.6.0'
|
||||||
|
//noinspection GradleCompatible
|
||||||
|
// implementation 'com.android.support:appcompat-v7:28.0.0'
|
||||||
|
|
||||||
|
|
||||||
|
implementation 'com.google.android.material:material:1.8.0'
|
||||||
|
implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
|
||||||
|
implementation fileTree(dir: 'libs', include: ['*.jar'])
|
||||||
|
// implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7"
|
||||||
|
//
|
||||||
|
// implementation 'com.android.support.constraint:constraint-layout:1.1.2'
|
||||||
|
implementation 'androidx.coordinatorlayout:coordinatorlayout:1.2.0'
|
||||||
|
testImplementation 'junit:junit:4.13.2'
|
||||||
|
androidTestImplementation 'androidx.test.ext:junit:1.1.5'
|
||||||
|
androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1'
|
||||||
|
}
|
@ -0,0 +1,21 @@
|
|||||||
|
# Add project specific ProGuard rules here.
|
||||||
|
# You can control the set of applied configuration files using the
|
||||||
|
# proguardFiles setting in build.gradle.
|
||||||
|
#
|
||||||
|
# For more details, see
|
||||||
|
# http://developer.android.com/guide/developing/tools/proguard.html
|
||||||
|
|
||||||
|
# If your project uses WebView with JS, uncomment the following
|
||||||
|
# and specify the fully qualified class name to the JavaScript interface
|
||||||
|
# class:
|
||||||
|
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
|
||||||
|
# public *;
|
||||||
|
#}
|
||||||
|
|
||||||
|
# Uncomment this to preserve the line number information for
|
||||||
|
# debugging stack traces.
|
||||||
|
#-keepattributes SourceFile,LineNumberTable
|
||||||
|
|
||||||
|
# If you keep the line number information, uncomment this to
|
||||||
|
# hide the original source file name.
|
||||||
|
#-renamesourcefileattribute SourceFile
|
@ -0,0 +1,24 @@
|
|||||||
|
package sgd.and04.layout
|
||||||
|
|
||||||
|
import androidx.test.platform.app.InstrumentationRegistry
|
||||||
|
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||||
|
|
||||||
|
import org.junit.Test
|
||||||
|
import org.junit.runner.RunWith
|
||||||
|
|
||||||
|
import org.junit.Assert.*
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Instrumented test, which will execute on an Android device.
|
||||||
|
*
|
||||||
|
* See [testing documentation](http://d.android.com/tools/testing).
|
||||||
|
*/
|
||||||
|
@RunWith(AndroidJUnit4::class)
|
||||||
|
class ExampleInstrumentedTest {
|
||||||
|
@Test
|
||||||
|
fun useAppContext() {
|
||||||
|
// Context of the app under test.
|
||||||
|
val appContext = InstrumentationRegistry.getInstrumentation().targetContext
|
||||||
|
assertEquals("sgd.and04.layout", appContext.packageName)
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,61 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
package="sgd.and04.layout">
|
||||||
|
|
||||||
|
<application
|
||||||
|
android:allowBackup="true"
|
||||||
|
android:dataExtractionRules="@xml/data_extraction_rules"
|
||||||
|
android:fullBackupContent="@xml/backup_rules"
|
||||||
|
android:icon="@mipmap/ic_launcher"
|
||||||
|
android:label="@string/app_name"
|
||||||
|
android:roundIcon="@mipmap/ic_launcher_round"
|
||||||
|
android:supportsRtl="true"
|
||||||
|
android:theme="@style/Theme.MyApplication"
|
||||||
|
tools:targetApi="31">
|
||||||
|
<activity
|
||||||
|
android:name=".ImageSwitcherActivity"
|
||||||
|
android:exported="false" />
|
||||||
|
<activity
|
||||||
|
android:name=".OpenGLActivity"
|
||||||
|
android:exported="false" />
|
||||||
|
<activity
|
||||||
|
android:name=".ScrollActivity"
|
||||||
|
android:exported="false" />
|
||||||
|
<activity
|
||||||
|
android:name=".GridActivity"
|
||||||
|
android:exported="false" />
|
||||||
|
<activity
|
||||||
|
android:name=".FrameActivity"
|
||||||
|
android:exported="false" />
|
||||||
|
<activity
|
||||||
|
android:name=".RelativeActivity"
|
||||||
|
android:exported="false" />
|
||||||
|
<activity
|
||||||
|
android:name=".TableActivity"
|
||||||
|
android:exported="false" />
|
||||||
|
<activity
|
||||||
|
android:name=".MainActivity"
|
||||||
|
android:exported="true">
|
||||||
|
<intent-filter>
|
||||||
|
<action android:name="android.intent.action.MAIN" />
|
||||||
|
|
||||||
|
<category android:name="android.intent.category.LAUNCHER" />
|
||||||
|
</intent-filter>
|
||||||
|
</activity>
|
||||||
|
<activity
|
||||||
|
android:name=".MainScreenActivity"
|
||||||
|
android:exported="false"
|
||||||
|
android:label="@string/app_name"
|
||||||
|
android:screenOrientation="portrait"
|
||||||
|
android:theme="@style/AppNoActionBar">
|
||||||
|
<intent-filter>
|
||||||
|
<category android:name="android.intent.category.VOICE" />
|
||||||
|
<!-- action android:name="com.google.android.gms.actions.SEARCH_ACTION" / -->
|
||||||
|
<action android:name="android.intent.action.VOICE_COMMAND" />
|
||||||
|
</intent-filter>
|
||||||
|
</activity>
|
||||||
|
<activity android:name=".DistanceActivity" />
|
||||||
|
</application>
|
||||||
|
|
||||||
|
</manifest>
|
@ -0,0 +1,94 @@
|
|||||||
|
package sgd.and04.layout
|
||||||
|
|
||||||
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
|
import android.os.Build
|
||||||
|
import android.os.Bundle
|
||||||
|
import android.widget.Button
|
||||||
|
import android.widget.SeekBar
|
||||||
|
import android.widget.TextView
|
||||||
|
import androidx.annotation.RequiresApi
|
||||||
|
import pavelsobolev.kotogl.Helpers.ZObjectsPos
|
||||||
|
|
||||||
|
// activity for setting distances of the scene's objects
|
||||||
|
class DistanceActivity : AppCompatActivity()
|
||||||
|
{
|
||||||
|
private var sbars: Array<SeekBar>? = null
|
||||||
|
private var txts: Array<TextView>? = null
|
||||||
|
private var txtids: IntArray? = null
|
||||||
|
private val MIN_DIST = 3
|
||||||
|
|
||||||
|
private var i = 0
|
||||||
|
|
||||||
|
@RequiresApi(api = Build.VERSION_CODES.N)
|
||||||
|
override fun onCreate(savedInstanceState: Bundle?)
|
||||||
|
{
|
||||||
|
super.onCreate(savedInstanceState)
|
||||||
|
setContentView(R.layout.activity_distance)
|
||||||
|
|
||||||
|
setArraysOfControls()
|
||||||
|
|
||||||
|
i = 0
|
||||||
|
while (i < 5)
|
||||||
|
{
|
||||||
|
setDataToInterface(sbars!![i], i, txts!![i])
|
||||||
|
sbars!![i].setOnSeekBarChangeListener(
|
||||||
|
object : SeekBar.OnSeekBarChangeListener {
|
||||||
|
var pos = i
|
||||||
|
override fun onProgressChanged(seekBar: SeekBar, progress: Int, fromUser: Boolean)
|
||||||
|
{
|
||||||
|
getDataFromInterface(sbars!![pos], pos, txts!![pos])
|
||||||
|
}
|
||||||
|
override fun onStopTrackingTouch(seekBar: SeekBar) {}
|
||||||
|
override fun onStartTrackingTouch(seekBar: SeekBar) {}
|
||||||
|
})
|
||||||
|
i++
|
||||||
|
}
|
||||||
|
|
||||||
|
(findViewById(R.id.buttonOk) as Button).setOnClickListener { view ->
|
||||||
|
setResult(AppCompatActivity.RESULT_OK)
|
||||||
|
finish()
|
||||||
|
}
|
||||||
|
|
||||||
|
(findViewById(R.id.buttonCancel) as Button).setOnClickListener { view ->
|
||||||
|
setResult(AppCompatActivity.RESULT_CANCELED)
|
||||||
|
finish()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun setArraysOfControls()
|
||||||
|
{
|
||||||
|
sbars = arrayOf(
|
||||||
|
findViewById(R.id.seekBarCentral) as SeekBar,
|
||||||
|
findViewById(R.id.seekBarLeft) as SeekBar,
|
||||||
|
findViewById(R.id.seekBarRight) as SeekBar,
|
||||||
|
findViewById(R.id.seekBarTop) as SeekBar,
|
||||||
|
findViewById(R.id.seekBarBottom) as SeekBar)
|
||||||
|
|
||||||
|
txts = arrayOf(
|
||||||
|
findViewById(R.id.textViewCenter) as TextView,
|
||||||
|
findViewById(R.id.textViewLeft) as TextView,
|
||||||
|
findViewById(R.id.textViewRight) as TextView,
|
||||||
|
findViewById(R.id.textViewTop) as TextView,
|
||||||
|
findViewById(R.id.textViewBottom) as TextView)
|
||||||
|
|
||||||
|
txtids = intArrayOf(
|
||||||
|
R.string.center_pos_txt,
|
||||||
|
R.string.left_pos_txt,
|
||||||
|
R.string.right_pos_txt,
|
||||||
|
R.string.top_pos_txt,
|
||||||
|
R.string.bottom_pos_txt)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun getDataFromInterface(sb: SeekBar, i: Int, tv: TextView)
|
||||||
|
{
|
||||||
|
tv.text = String.format("%s is %d units", getString(txtids!![i]), sb.progress + MIN_DIST)
|
||||||
|
ZObjectsPos.setPosition(i, -(sb.progress + MIN_DIST))
|
||||||
|
}
|
||||||
|
|
||||||
|
@RequiresApi(api = Build.VERSION_CODES.N)
|
||||||
|
private fun setDataToInterface(sb: SeekBar, i: Int, tv: TextView)
|
||||||
|
{
|
||||||
|
tv.text = String.format("%s is %d units", getString(txtids!![i]), -ZObjectsPos.getPosition(i))
|
||||||
|
sb.setProgress(-ZObjectsPos.getPosition(i) - MIN_DIST, true)
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,18 @@
|
|||||||
|
package sgd.and04.layout
|
||||||
|
|
||||||
|
import android.content.Intent
|
||||||
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
|
import android.os.Bundle
|
||||||
|
import android.view.View
|
||||||
|
|
||||||
|
class FrameActivity : AppCompatActivity() {
|
||||||
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
|
super.onCreate(savedInstanceState)
|
||||||
|
setContentView(R.layout.activity_frame)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun onLayoutClick(view: View) {
|
||||||
|
startActivity(Intent(this, MainActivity::class.java))
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,29 @@
|
|||||||
|
package sgd.and04.layout
|
||||||
|
|
||||||
|
import android.content.Intent
|
||||||
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
|
import android.os.Bundle
|
||||||
|
import android.view.View
|
||||||
|
|
||||||
|
class GridActivity : AppCompatActivity() {
|
||||||
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
|
super.onCreate(savedInstanceState)
|
||||||
|
setContentView(R.layout.activity_grid)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun onButtonTableLayoutClick(view: View) {
|
||||||
|
startActivity(Intent(this, TableActivity::class.java))
|
||||||
|
}
|
||||||
|
fun onButtonLinearLayoutClick(view: View) {
|
||||||
|
startActivity(Intent(this, MainActivity::class.java))
|
||||||
|
}
|
||||||
|
|
||||||
|
fun onButtonRelativeLayoutClick(view: View) {
|
||||||
|
startActivity(Intent(this, RelativeActivity::class.java))
|
||||||
|
}
|
||||||
|
|
||||||
|
fun onButtonFrameLayoutClick(view: View) {
|
||||||
|
startActivity(Intent(this, FrameActivity::class.java))
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,61 @@
|
|||||||
|
package pavelsobolev.kotogl.Helpers
|
||||||
|
|
||||||
|
import java.util.*
|
||||||
|
|
||||||
|
|
||||||
|
// the class calculates angle of tilt of a device (on the base of data from its accelerator)
|
||||||
|
object TiltData : Observable()
|
||||||
|
{
|
||||||
|
private var xTilt : Float = 0.0f
|
||||||
|
private var yTilt : Float = 0.0f
|
||||||
|
private var tiltScale : Float = 1.5f
|
||||||
|
|
||||||
|
init
|
||||||
|
{
|
||||||
|
setData(0.0f,0.0f)
|
||||||
|
tiltScale = 1.5f
|
||||||
|
}
|
||||||
|
|
||||||
|
// sets new tilt data for current object
|
||||||
|
fun setData(x:Float, y:Float)
|
||||||
|
{
|
||||||
|
if (Math.abs(x)>10 || Math.abs(y)>10) return;
|
||||||
|
|
||||||
|
xTilt = x
|
||||||
|
yTilt = y
|
||||||
|
setChanged()
|
||||||
|
notifyObservers()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getDirection(): TiltDirections
|
||||||
|
{
|
||||||
|
return getDirection(xTilt, yTilt)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getDirection(tiltX:Float, tiltY:Float) : TiltDirections
|
||||||
|
{
|
||||||
|
if (Math.abs(Math.abs(tiltX)-Math.abs(tiltY)) <= 3.0)
|
||||||
|
{
|
||||||
|
return TiltDirections.UNKNOWN
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Math.abs(tiltX) > Math.abs(tiltY))
|
||||||
|
{
|
||||||
|
if (tiltX < 0) return TiltDirections.RIGHT
|
||||||
|
if (tiltX > 0) return TiltDirections.LEFT
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (tiltY < 0) return TiltDirections.UP
|
||||||
|
if (tiltY > 0) return TiltDirections.DOWN
|
||||||
|
}
|
||||||
|
|
||||||
|
val threshold = 1.0f
|
||||||
|
if (tiltX > -threshold && tiltX < threshold && tiltY > -threshold && tiltY < threshold)
|
||||||
|
{
|
||||||
|
return TiltDirections.UNKNOWN
|
||||||
|
}
|
||||||
|
|
||||||
|
return TiltDirections.UNKNOWN
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,11 @@
|
|||||||
|
package pavelsobolev.kotogl.Helpers
|
||||||
|
|
||||||
|
/**
|
||||||
|
* enumeration describes the possible direction of tilts
|
||||||
|
* from device's accelerometer
|
||||||
|
*/
|
||||||
|
enum class TiltDirections
|
||||||
|
{
|
||||||
|
UP, DOWN, LEFT, RIGHT, UNKNOWN
|
||||||
|
//UNKNOWN means that there is not now strong tilt to some specific direction
|
||||||
|
}
|
@ -0,0 +1,30 @@
|
|||||||
|
package pavelsobolev.kotogl.Helpers
|
||||||
|
|
||||||
|
// distances from point of view to objects of 3D scene
|
||||||
|
object ZObjectsPos
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* 0=>central polyhedron z-position, 1=>left, 2=>right, 3=>top, 4=>bottom
|
||||||
|
*/
|
||||||
|
private var zPositions: IntArray
|
||||||
|
|
||||||
|
init
|
||||||
|
{
|
||||||
|
zPositions = IntArray(5)
|
||||||
|
zPositions[0] = -6
|
||||||
|
zPositions[1] = -7
|
||||||
|
zPositions[2] = -6
|
||||||
|
zPositions[3] = -7
|
||||||
|
zPositions[4] = -7
|
||||||
|
}
|
||||||
|
|
||||||
|
fun setPosition(pos: Int, newVal: Int)
|
||||||
|
{
|
||||||
|
zPositions[pos] = newVal
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getPosition(pos: Int): Int
|
||||||
|
{
|
||||||
|
return zPositions[pos]
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,67 @@
|
|||||||
|
package sgd.and04.layout
|
||||||
|
|
||||||
|
import android.content.Intent
|
||||||
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
|
import android.os.Bundle
|
||||||
|
import android.view.View
|
||||||
|
import android.widget.FrameLayout
|
||||||
|
import android.widget.ImageSwitcher
|
||||||
|
import android.widget.ImageView
|
||||||
|
import android.view.animation.AnimationUtils
|
||||||
|
import android.widget.Button
|
||||||
|
|
||||||
|
class ImageSwitcherActivity : AppCompatActivity() {
|
||||||
|
|
||||||
|
private val flowers = intArrayOf(R.drawable.flower1, R.drawable.flower2,
|
||||||
|
R.drawable.flower4)
|
||||||
|
private var index = 0
|
||||||
|
|
||||||
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
|
super.onCreate(savedInstanceState)
|
||||||
|
setContentView(R.layout.activity_image_switcher)
|
||||||
|
// create the ImageSwitcher
|
||||||
|
val imgSwitcher = ImageSwitcher(this)
|
||||||
|
|
||||||
|
imgSwitcher?.setFactory({
|
||||||
|
val imgView = ImageView(applicationContext)
|
||||||
|
imgView.scaleType = ImageView.ScaleType.CENTER
|
||||||
|
imgView.setPadding(20, 20, 20, 20)
|
||||||
|
imgView.setAdjustViewBounds(true)
|
||||||
|
imgView.setMaxHeight(2400)
|
||||||
|
|
||||||
|
imgView
|
||||||
|
})
|
||||||
|
|
||||||
|
val c_Layout = findViewById<FrameLayout>(R.id.scrollView)
|
||||||
|
//add ImageSwitcher in constraint layout
|
||||||
|
c_Layout?.addView(imgSwitcher)
|
||||||
|
|
||||||
|
// set the method and pass array as a parameter
|
||||||
|
imgSwitcher?.setImageResource(flowers[index])
|
||||||
|
|
||||||
|
val imgIn = AnimationUtils.loadAnimation(
|
||||||
|
this, android.R.anim.slide_in_left)
|
||||||
|
imgSwitcher?.inAnimation = imgIn
|
||||||
|
|
||||||
|
val imgOut = AnimationUtils.loadAnimation(
|
||||||
|
this, android.R.anim.slide_out_right)
|
||||||
|
imgSwitcher?.outAnimation = imgOut
|
||||||
|
|
||||||
|
// previous button functionality
|
||||||
|
val prev = findViewById<Button>(R.id.prev)
|
||||||
|
prev.setOnClickListener {
|
||||||
|
index = if (index - 1 >= 0) index - 1 else 1
|
||||||
|
imgSwitcher?.setImageResource(flowers[index])
|
||||||
|
}
|
||||||
|
// next button functionality
|
||||||
|
val next = findViewById<Button>(R.id.next)
|
||||||
|
next.setOnClickListener {
|
||||||
|
index = if (index + 1 < flowers.size) index +1 else 0
|
||||||
|
imgSwitcher?.setImageResource(flowers[index])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun onButtonExitClick(view: View) {
|
||||||
|
startActivity(Intent(this, MainActivity::class.java))
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,44 @@
|
|||||||
|
package sgd.and04.layout
|
||||||
|
|
||||||
|
import android.content.Intent
|
||||||
|
import android.os.Build
|
||||||
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
|
import android.os.Bundle
|
||||||
|
import android.view.View
|
||||||
|
import androidx.annotation.RequiresApi
|
||||||
|
|
||||||
|
class MainActivity : AppCompatActivity() {
|
||||||
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
|
super.onCreate(savedInstanceState)
|
||||||
|
setContentView(R.layout.activity_main)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun onButtonTableLayoutClick(view: View) {
|
||||||
|
startActivity(Intent(this, TableActivity::class.java))
|
||||||
|
}
|
||||||
|
|
||||||
|
fun onButtonRelativeLayoutClick(view: View) {
|
||||||
|
startActivity(Intent(this, RelativeActivity::class.java))
|
||||||
|
}
|
||||||
|
|
||||||
|
fun onButtonFrameLayoutClick(view: View) {
|
||||||
|
startActivity(Intent(this, FrameActivity::class.java))
|
||||||
|
}
|
||||||
|
|
||||||
|
fun onButtonGridLayoutClick(view: View) {
|
||||||
|
startActivity(Intent(this, GridActivity::class.java))
|
||||||
|
}
|
||||||
|
|
||||||
|
fun onButtonScrollLayoutClick(view: View) {
|
||||||
|
startActivity(Intent(this, ScrollActivity::class.java))
|
||||||
|
}
|
||||||
|
|
||||||
|
fun onButtonImageSwitcherClick(view: View) {
|
||||||
|
startActivity(Intent(this, ImageSwitcherActivity::class.java))
|
||||||
|
}
|
||||||
|
|
||||||
|
@RequiresApi(Build.VERSION_CODES.O)
|
||||||
|
fun onButtonOpenGLClick(view: View) {
|
||||||
|
startActivity(Intent(this, MainScreenActivity::class.java))
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,332 @@
|
|||||||
|
package sgd.and04.layout
|
||||||
|
|
||||||
|
import android.annotation.SuppressLint
|
||||||
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
|
import android.content.Context
|
||||||
|
import android.content.Intent
|
||||||
|
import android.graphics.PixelFormat
|
||||||
|
import android.hardware.Sensor
|
||||||
|
import android.hardware.SensorEvent
|
||||||
|
import android.hardware.SensorEventListener
|
||||||
|
import android.hardware.SensorManager
|
||||||
|
import android.os.Build
|
||||||
|
import android.os.Bundle
|
||||||
|
import android.speech.RecognizerIntent
|
||||||
|
import androidx.annotation.RequiresApi
|
||||||
|
import androidx.constraintlayout.widget.ConstraintLayout
|
||||||
|
|
||||||
|
import androidx.core.content.ContextCompat
|
||||||
|
import androidx.appcompat.widget.Toolbar
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
import android.view.Menu
|
||||||
|
import android.view.MenuItem
|
||||||
|
import android.view.View
|
||||||
|
import android.view.ViewGroup
|
||||||
|
import kotlinx.android.synthetic.main.activity_main_screen.*
|
||||||
|
|
||||||
|
import pavelsobolev.kotogl.Helpers.TiltData
|
||||||
|
//import pavelsobolev.kotogl.R
|
||||||
|
import pavelsobolev.kotogl.Space3D.SpaceGLSurface
|
||||||
|
import pavelsobolev.kotogl.Spiral2D.MyGLSurfaceView
|
||||||
|
import sgd.and04.layout.R
|
||||||
|
|
||||||
|
// activity contains tabs for 2D and 3D scenes
|
||||||
|
@RequiresApi(api = Build.VERSION_CODES.O)
|
||||||
|
class MainScreenActivity : AppCompatActivity(), SensorEventListener
|
||||||
|
{
|
||||||
|
|
||||||
|
private var mSensorManager: SensorManager? = null
|
||||||
|
private var mAccelerometer: Sensor? = null
|
||||||
|
|
||||||
|
private var spaceGLSurface: SpaceGLSurface? = null //
|
||||||
|
private var flatGLSurface: MyGLSurfaceView? = null
|
||||||
|
|
||||||
|
internal var mainL: ConstraintLayout? = null
|
||||||
|
private var active: View? = null
|
||||||
|
|
||||||
|
private var isTiltable = false
|
||||||
|
private var useTilt: Boolean = false
|
||||||
|
|
||||||
|
private var mMyMenu: Menu? = null
|
||||||
|
|
||||||
|
@SuppressLint("RestrictedApi")
|
||||||
|
override fun onCreate(savedInstanceState: Bundle?)
|
||||||
|
{
|
||||||
|
super.onCreate(savedInstanceState)
|
||||||
|
|
||||||
|
setContentView(R.layout.activity_main_screen) //move
|
||||||
|
|
||||||
|
val toolbar = findViewById(R.id.toolbar) as Toolbar
|
||||||
|
setSupportActionBar(toolbar)
|
||||||
|
|
||||||
|
// main layout is a container for OpenGL surfaces and belongs to main activity
|
||||||
|
mainL = findViewById(R.id.mainLayout)
|
||||||
|
|
||||||
|
// ----------- creation of GL rendering surfaces
|
||||||
|
|
||||||
|
spaceGLSurface = SpaceGLSurface(this, true) //observer of mTiltData
|
||||||
|
|
||||||
|
|
||||||
|
TiltData.addObserver(spaceGLSurface)
|
||||||
|
|
||||||
|
flatGLSurface = MyGLSurfaceView(this)
|
||||||
|
TiltData.addObserver(flatGLSurface)
|
||||||
|
|
||||||
|
// loading view into main activity
|
||||||
|
|
||||||
|
mainL!!.addView(spaceGLSurface, //spaceGLSurface, // flatGLSurface,
|
||||||
|
ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
|
||||||
|
ViewGroup.LayoutParams.MATCH_PARENT))
|
||||||
|
|
||||||
|
active = spaceGLSurface
|
||||||
|
|
||||||
|
// -------- setting up the accelerometer
|
||||||
|
setAccelerometer()
|
||||||
|
|
||||||
|
// setup voice command handler
|
||||||
|
fab.visibility = View.GONE
|
||||||
|
setVoiceCommandMode()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun setVoiceCommandMode()
|
||||||
|
{
|
||||||
|
fab.setOnClickListener { view ->
|
||||||
|
intent = Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH)
|
||||||
|
intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL,
|
||||||
|
RecognizerIntent.LANGUAGE_MODEL_FREE_FORM);
|
||||||
|
startActivityForResult(intent, 1010); //result handled in "onActivityResult"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun setAccelerometer()
|
||||||
|
{
|
||||||
|
useTilt = false
|
||||||
|
mSensorManager = getSystemService(Context.SENSOR_SERVICE) as SensorManager
|
||||||
|
mAccelerometer = mSensorManager!!.getDefaultSensor(Sensor.TYPE_ACCELEROMETER)
|
||||||
|
TiltData.setData(0.0f, 0.0f)
|
||||||
|
}
|
||||||
|
|
||||||
|
internal var mTiltCounter = 0 // counter of
|
||||||
|
internal var mTiltCounterThreshold = 10 //gap between consecutive accelerometers events which are handled
|
||||||
|
|
||||||
|
override fun onSensorChanged(sensorEvent: SensorEvent)
|
||||||
|
{
|
||||||
|
if (!isTiltable) return
|
||||||
|
|
||||||
|
if (sensorEvent.sensor.type != Sensor.TYPE_ACCELEROMETER) return
|
||||||
|
|
||||||
|
val x = sensorEvent.values[0]
|
||||||
|
val y = sensorEvent.values[1]
|
||||||
|
|
||||||
|
//in order not ot react to any change of accelerometer (every mTiltCounterThreshold-th event accepted)
|
||||||
|
if (mTiltCounter == mTiltCounterThreshold) TiltData.setData(x, y) // <<--- change tilt data
|
||||||
|
if (mTiltCounter++ > mTiltCounterThreshold) mTiltCounter = 0
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onAccuracyChanged(sensor: Sensor, i: Int)
|
||||||
|
{
|
||||||
|
//this method must be implemented even if not used
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onResume()
|
||||||
|
{
|
||||||
|
super.onResume()
|
||||||
|
if (isTiltable)
|
||||||
|
mSensorManager!!.registerListener(this, mAccelerometer, SensorManager.SENSOR_DELAY_NORMAL)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onPause()
|
||||||
|
{
|
||||||
|
super.onPause()
|
||||||
|
if (isTiltable)
|
||||||
|
mSensorManager!!.unregisterListener(this)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onCreateOptionsMenu(menu: Menu): Boolean
|
||||||
|
{
|
||||||
|
menuInflater.inflate(R.menu.menu_main_screen, menu)
|
||||||
|
mMyMenu = menu
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
// main menu events
|
||||||
|
|
||||||
|
@SuppressLint("RestrictedApi")
|
||||||
|
fun menuManualMode(item : MenuItem)
|
||||||
|
{
|
||||||
|
if (spaceGLSurface!!.isHandleMode)
|
||||||
|
{
|
||||||
|
spaceGLSurface!!.isHandleMode = false
|
||||||
|
item.icon = ContextCompat.getDrawable(this, R.drawable.touch)
|
||||||
|
fab.visibility = View.VISIBLE
|
||||||
|
mMyMenu!!.findItem(R.id.action_Tilt).setVisible(true)
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
spaceGLSurface!!.isHandleMode = true
|
||||||
|
item.icon = ContextCompat.getDrawable(this, R.drawable.if_ic_history_48px_352426)
|
||||||
|
fab.visibility = View.GONE
|
||||||
|
mMyMenu!!.findItem(R.id.action_Tilt).setVisible(false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressLint("RestrictedApi")
|
||||||
|
private fun menuToggle2D()
|
||||||
|
{
|
||||||
|
mainL!!.removeView(active)
|
||||||
|
active = flatGLSurface
|
||||||
|
mainL!!.addView(flatGLSurface, // cubeGLSurface,
|
||||||
|
ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
|
||||||
|
ViewGroup.LayoutParams.MATCH_PARENT))
|
||||||
|
|
||||||
|
mainL!!.bringChildToFront(flatGLSurface)
|
||||||
|
mainL!!.setBackground(ContextCompat.getDrawable(this, R.drawable.app_background))
|
||||||
|
|
||||||
|
setItemsVisibility(false)
|
||||||
|
fab.visibility = View.GONE
|
||||||
|
mMyMenu!!.findItem(R.id.action_Tilt).setVisible(true)
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressLint("RestrictedApi")
|
||||||
|
private fun menuToggle3D()
|
||||||
|
{
|
||||||
|
if (active === spaceGLSurface) return
|
||||||
|
|
||||||
|
mainL!!.removeView(active)
|
||||||
|
active = spaceGLSurface
|
||||||
|
mainL!!.addView(spaceGLSurface,
|
||||||
|
ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
|
||||||
|
ViewGroup.LayoutParams.MATCH_PARENT))
|
||||||
|
|
||||||
|
setItemsVisibility(true)
|
||||||
|
|
||||||
|
if(isTiltable)
|
||||||
|
fab.visibility = View.GONE
|
||||||
|
else
|
||||||
|
fab.visibility = View.VISIBLE
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressLint("RestrictedApi")
|
||||||
|
private fun menuToggleAccelerometer(item: MenuItem)
|
||||||
|
{
|
||||||
|
isTiltable = !isTiltable
|
||||||
|
|
||||||
|
if (isTiltable)
|
||||||
|
{
|
||||||
|
fab.visibility = View.GONE // disable voice commands
|
||||||
|
|
||||||
|
mSensorManager!!.registerListener(this, mAccelerometer, SensorManager.SENSOR_DELAY_NORMAL)
|
||||||
|
item.icon = ContextCompat.getDrawable(this, R.drawable.nonrotate)
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
fab.visibility = View.VISIBLE // enable voice command
|
||||||
|
|
||||||
|
mSensorManager!!.unregisterListener(this)
|
||||||
|
item.icon = ContextCompat.getDrawable(this, R.drawable.rotate)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private fun menuInvokeDistanceActivity()
|
||||||
|
{
|
||||||
|
val intent = Intent(this, DistanceActivity::class.java)
|
||||||
|
startActivityForResult(intent, AppCompatActivity.RESULT_OK)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun menuToggleRotation(item: MenuItem)
|
||||||
|
{
|
||||||
|
if (spaceGLSurface!!.isRotationDirection)
|
||||||
|
{
|
||||||
|
spaceGLSurface!!.isRotationDirection = false
|
||||||
|
item.icon = ContextCompat.getDrawable(this, R.drawable.leftright)
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
spaceGLSurface!!.isRotationDirection = true
|
||||||
|
item.icon = ContextCompat.getDrawable(this, R.drawable.updown)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onOptionsItemSelected(item: MenuItem): Boolean
|
||||||
|
{
|
||||||
|
when (item.itemId)
|
||||||
|
{
|
||||||
|
R.id.action_manual -> menuManualMode(item)
|
||||||
|
R.id.action_2D -> menuToggle2D()
|
||||||
|
R.id.action_3D -> menuToggle3D()
|
||||||
|
R.id.action_Tilt -> menuToggleAccelerometer(item)
|
||||||
|
R.id.action_settingsDistance -> menuInvokeDistanceActivity()
|
||||||
|
R.id.action_swap_textures -> spaceGLSurface!!.passSwapTextures()
|
||||||
|
R.id.action_Rotate -> menuToggleRotation(item)
|
||||||
|
R.id.action_exit -> returnToLayoutList()
|
||||||
|
}
|
||||||
|
return super.onOptionsItemSelected(item)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun returnToLayoutList() {
|
||||||
|
startActivity(Intent(this, MainActivity::class.java))
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// show or hide some buttons in the main menu
|
||||||
|
@SuppressLint("RestrictedApi")
|
||||||
|
private fun setItemsVisibility(visible: Boolean)
|
||||||
|
{
|
||||||
|
mMyMenu!!.findItem(R.id.action_manual).isVisible = visible
|
||||||
|
mMyMenu!!.findItem(R.id.action_swap_textures).isVisible = visible
|
||||||
|
mMyMenu!!.findItem(R.id.action_settingsDistance).isVisible = visible
|
||||||
|
mMyMenu!!.findItem(R.id.action_Rotate).isVisible = visible
|
||||||
|
if (/*active==spaceGLSurface && */spaceGLSurface!!.isHandleMode || isTiltable)
|
||||||
|
fab.visibility = View.GONE
|
||||||
|
else
|
||||||
|
fab.visibility = View.VISIBLE
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// after returning from activity "DistanceActivity"
|
||||||
|
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?)
|
||||||
|
{
|
||||||
|
super.onActivityResult(requestCode, resultCode, data)
|
||||||
|
if (active == flatGLSurface) // commands for flat scene
|
||||||
|
{
|
||||||
|
if (requestCode == 1010 && resultCode == RESULT_OK) // speech recognition results arrived
|
||||||
|
{
|
||||||
|
//TODO: make this work
|
||||||
|
//decodeFlatVoiceCommands(data!!.getStringArrayListExtra(RecognizerIntent.EXTRA_RESULTS))
|
||||||
|
//var results = data!!.getStringArrayListExtra(RecognizerIntent.EXTRA_RESULTS)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// else - commands for 3D scene
|
||||||
|
if (requestCode == 1010 && resultCode == RESULT_OK) // speech recognition results arrived
|
||||||
|
{
|
||||||
|
//decodeSpaceVoiceCommands(data!!.getStringArrayListExtra(RecognizerIntent.EXTRA_RESULTS))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// new distance data results arrived
|
||||||
|
if (resultCode == AppCompatActivity.RESULT_OK) spaceGLSurface!!.updateDistance()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun decodeFlatVoiceCommands(results : ArrayList<String>)
|
||||||
|
{
|
||||||
|
if (results.count()==0) return
|
||||||
|
|
||||||
|
var spokenText: String = results.get(0)
|
||||||
|
flatGLSurface!!.sendVoiceCommandData(spokenText.toLowerCase())
|
||||||
|
}
|
||||||
|
|
||||||
|
fun decodeSpaceVoiceCommands(results : ArrayList<String>)
|
||||||
|
{
|
||||||
|
if (results.count()==0) return
|
||||||
|
|
||||||
|
var spokenText: String = results.get(0)
|
||||||
|
spaceGLSurface!!.sendVoiceCommandToRenderer(spokenText.toLowerCase())
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,14 @@
|
|||||||
|
package sgd.and04.layout
|
||||||
|
|
||||||
|
import android.opengl.GLSurfaceView
|
||||||
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
|
import android.os.Bundle
|
||||||
|
|
||||||
|
class OpenGLActivity : AppCompatActivity() {
|
||||||
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
|
super.onCreate(savedInstanceState)
|
||||||
|
setContentView(R.layout.activity_open_glactivity)
|
||||||
|
val mySurfaceView :GLSurfaceView = findViewById(R.id.my_surface_view);
|
||||||
|
mySurfaceView.setEGLContextClientVersion(2);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,29 @@
|
|||||||
|
package sgd.and04.layout
|
||||||
|
|
||||||
|
import android.content.Intent
|
||||||
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
|
import android.os.Bundle
|
||||||
|
import android.view.View
|
||||||
|
|
||||||
|
class RelativeActivity : AppCompatActivity() {
|
||||||
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
|
super.onCreate(savedInstanceState)
|
||||||
|
setContentView(R.layout.activity_relative)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun onButtonLinearLayoutClick(view: View) {
|
||||||
|
startActivity(Intent(this, MainActivity::class.java))
|
||||||
|
}
|
||||||
|
|
||||||
|
fun onButtonTableLayoutClick(view: View) {
|
||||||
|
startActivity(Intent(this, TableActivity::class.java))
|
||||||
|
}
|
||||||
|
|
||||||
|
fun onButtonFrameLayoutClick(view: View) {
|
||||||
|
startActivity(Intent(this, FrameActivity::class.java))
|
||||||
|
}
|
||||||
|
|
||||||
|
fun onButtonGridLayoutClick(view: View) {
|
||||||
|
startActivity(Intent(this, GridActivity::class.java))
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,17 @@
|
|||||||
|
package sgd.and04.layout
|
||||||
|
|
||||||
|
import android.content.Intent
|
||||||
|
import android.os.Bundle
|
||||||
|
import android.view.View
|
||||||
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
|
|
||||||
|
class ScrollActivity : AppCompatActivity(){
|
||||||
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
|
super.onCreate(savedInstanceState)
|
||||||
|
setContentView(R.layout.activity_scroll)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun onButtonExitClick(view: View) {
|
||||||
|
startActivity(Intent(this, MainActivity::class.java))
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,85 @@
|
|||||||
|
package pavelsobolev.kotogl.Space3D
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import android.graphics.BitmapFactory
|
||||||
|
import android.opengl.GLES20
|
||||||
|
import android.opengl.GLUtils
|
||||||
|
import java.io.BufferedReader
|
||||||
|
import java.io.IOException
|
||||||
|
import java.io.InputStreamReader
|
||||||
|
|
||||||
|
/**
|
||||||
|
* helper class of static methods for generating string
|
||||||
|
* sources of OpenGL pipeline's programs
|
||||||
|
*/
|
||||||
|
object ShaderSource
|
||||||
|
{
|
||||||
|
|
||||||
|
fun getTextFromResourceFile(appContext: Context, appResourceId: Int): String?
|
||||||
|
{
|
||||||
|
val resourceReader = BufferedReader(
|
||||||
|
InputStreamReader(appContext.resources.openRawResource(appResourceId)))
|
||||||
|
|
||||||
|
var llineFromFile : String = ""
|
||||||
|
var shaderText = StringBuilder()
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
llineFromFile = resourceReader.readLine()
|
||||||
|
while (llineFromFile!= null)
|
||||||
|
{
|
||||||
|
shaderText.append(llineFromFile)
|
||||||
|
shaderText.append('\n')
|
||||||
|
try {
|
||||||
|
llineFromFile = resourceReader.readLine()
|
||||||
|
}
|
||||||
|
catch (ee:Exception)
|
||||||
|
{
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (e: IOException)
|
||||||
|
{
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
return shaderText.toString()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun readTextureFromResource(appContext: Context, puctId: Int): Int
|
||||||
|
{
|
||||||
|
val handleOfTexture = IntArray(1)
|
||||||
|
|
||||||
|
GLES20.glGenTextures(1, handleOfTexture, 0)
|
||||||
|
|
||||||
|
if (handleOfTexture[0] != 0)
|
||||||
|
{
|
||||||
|
val bitmapOptions = BitmapFactory.Options()
|
||||||
|
bitmapOptions.inScaled = false // No pre-scaling
|
||||||
|
|
||||||
|
// retrieving binary data of resource
|
||||||
|
val bitmap = BitmapFactory.decodeResource(appContext.resources,
|
||||||
|
puctId, bitmapOptions)
|
||||||
|
|
||||||
|
// texture binding
|
||||||
|
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, handleOfTexture[0])
|
||||||
|
|
||||||
|
// setting of color and coordinates approximation of texture
|
||||||
|
GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_NEAREST)
|
||||||
|
GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_NEAREST)
|
||||||
|
|
||||||
|
// bitmap loading
|
||||||
|
GLUtils.texImage2D(GLES20.GL_TEXTURE_2D, 0, bitmap, 0)
|
||||||
|
|
||||||
|
// remove binary data from system memory
|
||||||
|
bitmap.recycle()
|
||||||
|
}
|
||||||
|
|
||||||
|
if (handleOfTexture[0] == 0) {
|
||||||
|
throw RuntimeException("Impossible to load texture.")
|
||||||
|
}
|
||||||
|
|
||||||
|
return handleOfTexture[0]
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,764 @@
|
|||||||
|
package sgd.and04.layout
|
||||||
|
import sgd.and04.layout.R
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import android.opengl.GLES20
|
||||||
|
import android.opengl.GLSurfaceView
|
||||||
|
import android.opengl.Matrix
|
||||||
|
import android.os.SystemClock
|
||||||
|
|
||||||
|
import pavelsobolev.kotogl.Helpers.TiltData
|
||||||
|
import pavelsobolev.kotogl.Helpers.TiltDirections
|
||||||
|
import pavelsobolev.kotogl.Helpers.ZObjectsPos
|
||||||
|
import pavelsobolev.kotogl.Space3D.ShaderSource
|
||||||
|
import pavelsobolev.kotogl.Space3D.VertexSource
|
||||||
|
import java.nio.ByteBuffer
|
||||||
|
import java.nio.ByteOrder
|
||||||
|
import java.nio.FloatBuffer
|
||||||
|
import javax.microedition.khronos.egl.EGLConfig
|
||||||
|
import javax.microedition.khronos.opengles.GL10
|
||||||
|
|
||||||
|
|
||||||
|
//class for representing of OpenGL renderer (used for drawing on activity surface)
|
||||||
|
|
||||||
|
// private val mActivityContext: Context,// reference to current activity context
|
||||||
|
// internal var mTiltData: TiltData, // device tilt data for changing of the direction of rotation of polyhedrons
|
||||||
|
// private val mTextures: IntArray) // data for texture binding
|
||||||
|
class SpaceGLRenderer(private val mActivityContext: Context,
|
||||||
|
private val mTextures: IntArray) : GLSurfaceView.Renderer
|
||||||
|
{
|
||||||
|
|
||||||
|
var mHandleMode: Boolean = false
|
||||||
|
|
||||||
|
//angles of rotation
|
||||||
|
private var mAngleBodies: Float = 0.toFloat()
|
||||||
|
private var mAngleCenter: Float = 0.toFloat()
|
||||||
|
private var mGlobalAngle: Float = 0.toFloat()
|
||||||
|
|
||||||
|
//vector around which scene is rotating (this value is affected by accelerometer)
|
||||||
|
private var mRotationVector: FloatArray? = null
|
||||||
|
|
||||||
|
// attribute of direction of rotation by touch gestures
|
||||||
|
//if true oX is rotational axis, otherwise Y is rotational axis
|
||||||
|
private var mHadleRotation: Boolean = false
|
||||||
|
|
||||||
|
//mModelMtrx stores the model matrix
|
||||||
|
private var mModelMtrx = FloatArray(16)
|
||||||
|
|
||||||
|
//private val mGlobalMatrix = FloatArray(16)
|
||||||
|
|
||||||
|
//mViewMtrx stores the view matrix
|
||||||
|
private val mViewMtrx = FloatArray(16)
|
||||||
|
|
||||||
|
// mProjMtrx stores the projection matrix
|
||||||
|
private val mProjMtrx = FloatArray(16)
|
||||||
|
|
||||||
|
//mMVPMtrx stores the final matrix
|
||||||
|
private val mMVPMtrx = FloatArray(16)
|
||||||
|
|
||||||
|
|
||||||
|
// mLightMdlMtrx stores a copy of the model matrix for the light position
|
||||||
|
private val mLightMdlMtrx = FloatArray(16)
|
||||||
|
|
||||||
|
// model data in a program's float buffer (for hexahedron's coordinates)
|
||||||
|
private var mHexahedronPos: FloatBuffer? = null
|
||||||
|
|
||||||
|
|
||||||
|
// model data in a program's float buffer (for hexahedron's colors)
|
||||||
|
private var mHexahedronClrs: FloatBuffer? = null
|
||||||
|
|
||||||
|
//model data in a program's float buffer (for hexahedron's normal vectors)
|
||||||
|
private var mHexahedronNrmls: FloatBuffer? = null
|
||||||
|
|
||||||
|
// model data in a program's float buffer (for tetrahedron's coordinates)
|
||||||
|
private var mTetraPosns: FloatBuffer? = null
|
||||||
|
|
||||||
|
// model data in a program's float buffer (for tetrahedron's colors)
|
||||||
|
private var mTetraClrs: FloatBuffer? = null
|
||||||
|
|
||||||
|
// model data in a program's float buffer (for tetrahedron's normal vectors)
|
||||||
|
private var mTetraNrmls: FloatBuffer? = null
|
||||||
|
|
||||||
|
// transformation matrix
|
||||||
|
private var mMVPMtrxHndl: Int = 0
|
||||||
|
|
||||||
|
// modelview matrix
|
||||||
|
private var mMVMtrxHndl: Int = 0
|
||||||
|
|
||||||
|
// light position
|
||||||
|
private var mLightPsHndl: Int = 0
|
||||||
|
|
||||||
|
// position information (hexahedron)
|
||||||
|
private var mHexahedronPstnHndl: Int = 0
|
||||||
|
|
||||||
|
// color information (hexahedron)
|
||||||
|
private var mHexahedronClrHndl: Int = 0
|
||||||
|
|
||||||
|
// normal vector information (hexahedron)
|
||||||
|
private var mHexahedronNrmlHndl: Int = 0
|
||||||
|
|
||||||
|
// position information (tetrahedron)
|
||||||
|
private var mTetraPstnHndl: Int = 0
|
||||||
|
|
||||||
|
// color information (tetrahedron)
|
||||||
|
private var mTetraClrHndl: Int = 0
|
||||||
|
|
||||||
|
// normal vector information (tetrahedron)
|
||||||
|
private var mTetraNrmlHndl: Int = 0
|
||||||
|
|
||||||
|
// size of float number in bytes
|
||||||
|
private val mFloatSize : Int = 4
|
||||||
|
|
||||||
|
// number of parameters for the position of one vertex (x,y,z)
|
||||||
|
private val mPosDataSize : Int = 3
|
||||||
|
|
||||||
|
// number of parameters for the color data for each vertes (red, green,blue, alpha)
|
||||||
|
private val mClrDataSize : Int = 4
|
||||||
|
|
||||||
|
// number of coordinates of normal vector
|
||||||
|
private val mNrmlDataSize : Int = 3
|
||||||
|
|
||||||
|
|
||||||
|
// ********* ------------- light positions --------- **********************
|
||||||
|
|
||||||
|
// Used to keep light source in the center of the origin in model coordinates
|
||||||
|
private val mLightPosInModelCoords = floatArrayOf(0.0f, 0.0f, 0.0f, 1.0f)
|
||||||
|
|
||||||
|
// Used to keep the current position of the light
|
||||||
|
private val mLightPosInWorldCoords = FloatArray(4)
|
||||||
|
|
||||||
|
// Used to keep the transformed position of the light
|
||||||
|
private val mLightPosInLookAtCoords = FloatArray(4)
|
||||||
|
|
||||||
|
|
||||||
|
// -------- OpenGL ES programs handles
|
||||||
|
// hexahedron's program
|
||||||
|
private var mHexahedronVertexPrgrmHndl: Int = 0
|
||||||
|
|
||||||
|
// tetrahedron's program
|
||||||
|
private var mTetraVertexPrgrmHndl: Int = 0
|
||||||
|
|
||||||
|
// light's program
|
||||||
|
private var mLightPointPrgrmHndl: Int = 0
|
||||||
|
|
||||||
|
|
||||||
|
// -------------- texture handling -------------------------
|
||||||
|
|
||||||
|
// Store our model data in a float buffer. */
|
||||||
|
private var mHexahedronTextureCoords: FloatBuffer? = null
|
||||||
|
|
||||||
|
// This will be used to pass in the texture. */
|
||||||
|
private var mTextureUniformHndl: Int = 0
|
||||||
|
|
||||||
|
// This will be used to pass in model texture coordinate information. */
|
||||||
|
private var mTextureCoordHndl: Int = 0
|
||||||
|
|
||||||
|
// Size of the texture coordinate data in elements. */
|
||||||
|
private val mTextureCoordinateDtSz = 2
|
||||||
|
|
||||||
|
// Array of textures data */
|
||||||
|
private val mTextureDataHndls: IntArray
|
||||||
|
|
||||||
|
|
||||||
|
// position characteristics of camera
|
||||||
|
//private val xMove = 0.0f
|
||||||
|
//private val yMove = 0.0f
|
||||||
|
private var lkX = 0.0f
|
||||||
|
private var lkY = 0.0f
|
||||||
|
//private val lkZ = -5.0f
|
||||||
|
|
||||||
|
init
|
||||||
|
{
|
||||||
|
mTextureDataHndls = IntArray(14)
|
||||||
|
|
||||||
|
mAngleBodies = 0.0f // rotational angles
|
||||||
|
mAngleCenter = 0.0f
|
||||||
|
mGlobalAngle = 0.0f
|
||||||
|
|
||||||
|
mRotationVector = floatArrayOf(0.0f, 0.0f, 1.0f)
|
||||||
|
|
||||||
|
mHadleRotation = false
|
||||||
|
|
||||||
|
initHexahedron()
|
||||||
|
|
||||||
|
initTetrahedron()
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
fun initHexahedron()
|
||||||
|
{
|
||||||
|
// hexahedron settings -------------------
|
||||||
|
|
||||||
|
// X, Y, Z
|
||||||
|
val hexahedronPositionData = VertexSource.HexahedronCoordinates
|
||||||
|
|
||||||
|
// R, G, B, A
|
||||||
|
val hexahedronColorData = VertexSource.HexahedronColors
|
||||||
|
|
||||||
|
// X, Y, Z
|
||||||
|
val hexahedronNormalData = VertexSource.HexahedronNormalVectors
|
||||||
|
|
||||||
|
// Initialize the buffers or hexahedron
|
||||||
|
mHexahedronPos = ByteBuffer.allocateDirect(hexahedronPositionData.size * mFloatSize)
|
||||||
|
.order(ByteOrder.nativeOrder()).asFloatBuffer()
|
||||||
|
mHexahedronPos!!.put(hexahedronPositionData).position(0)
|
||||||
|
|
||||||
|
mHexahedronClrs = ByteBuffer.allocateDirect(hexahedronColorData.size * mFloatSize)
|
||||||
|
.order(ByteOrder.nativeOrder()).asFloatBuffer()
|
||||||
|
mHexahedronClrs!!.put(hexahedronColorData).position(0)
|
||||||
|
|
||||||
|
mHexahedronNrmls = ByteBuffer.allocateDirect(hexahedronNormalData.size * mFloatSize)
|
||||||
|
.order(ByteOrder.nativeOrder()).asFloatBuffer()
|
||||||
|
mHexahedronNrmls!!.put(hexahedronNormalData).position(0)
|
||||||
|
|
||||||
|
val hexahedronTextureCoordinateData = VertexSource.HexahedronTextureCoordinateData
|
||||||
|
mHexahedronTextureCoords = ByteBuffer.allocateDirect(hexahedronTextureCoordinateData.size * mFloatSize).order(ByteOrder.nativeOrder()).asFloatBuffer()
|
||||||
|
mHexahedronTextureCoords!!.put(hexahedronTextureCoordinateData).position(0)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun initTetrahedron()
|
||||||
|
{
|
||||||
|
// -------------- tetrahedron settings
|
||||||
|
|
||||||
|
// X, Y, Z
|
||||||
|
val tetraPositionData = VertexSource.TetrahedronCoordinates
|
||||||
|
|
||||||
|
// R, G, B, A
|
||||||
|
val tetraColorData = VertexSource.TetrahedronColors
|
||||||
|
|
||||||
|
// X, Y, Z
|
||||||
|
val tetraNormalData = VertexSource.TetrahedronNormalVectors
|
||||||
|
|
||||||
|
// Initialize the buffers or hexahedron
|
||||||
|
mTetraPosns = ByteBuffer.allocateDirect(tetraPositionData.size * mFloatSize)
|
||||||
|
.order(ByteOrder.nativeOrder()).asFloatBuffer()
|
||||||
|
mTetraPosns!!.put(tetraPositionData).position(0)
|
||||||
|
|
||||||
|
mTetraClrs = ByteBuffer.allocateDirect(tetraColorData.size * mFloatSize)
|
||||||
|
.order(ByteOrder.nativeOrder()).asFloatBuffer()
|
||||||
|
mTetraClrs!!.put(tetraColorData).position(0)
|
||||||
|
|
||||||
|
mTetraNrmls = ByteBuffer.allocateDirect(tetraNormalData.size * mFloatSize)
|
||||||
|
.order(ByteOrder.nativeOrder()).asFloatBuffer()
|
||||||
|
mTetraNrmls!!.put(tetraNormalData).position(0)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// init scene
|
||||||
|
override fun onSurfaceCreated(glOldVers: GL10, glCnfg: EGLConfig)
|
||||||
|
{
|
||||||
|
// OGL global settings
|
||||||
|
GLES20.glClearColor(0.0f, 0.0f, 0.0f, 0.3f)
|
||||||
|
GLES20.glEnable(GLES20.GL_CULL_FACE)
|
||||||
|
GLES20.glEnable(GLES20.GL_DEPTH_TEST)
|
||||||
|
|
||||||
|
// camera settings
|
||||||
|
val eX = 0.0f
|
||||||
|
val eY = 0.0f
|
||||||
|
val eZ = -0.5f
|
||||||
|
var lkX = 0.0f
|
||||||
|
val lkY = 0.0f
|
||||||
|
val lkZ = -5.0f
|
||||||
|
val upOX = 0.0f
|
||||||
|
val upOY = 1.0f
|
||||||
|
val upOZ = 0.0f
|
||||||
|
|
||||||
|
Matrix.setLookAtM(mViewMtrx, 0, eX, eY, eZ, lkX, lkY, lkZ, upOX, upOY, upOZ)
|
||||||
|
|
||||||
|
val vertexShdr : String? = ShaderSource.getTextFromResourceFile(mActivityContext,
|
||||||
|
R.raw.body_vertex_shader)
|
||||||
|
val fragmentShdr : String? = ShaderSource.getTextFromResourceFile(mActivityContext,
|
||||||
|
R.raw.body_fragment_shader)
|
||||||
|
|
||||||
|
if (vertexShdr==null || fragmentShdr==null)
|
||||||
|
{
|
||||||
|
System.exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
val vertexShdrHndl = compileShader(GLES20.GL_VERTEX_SHADER, vertexShdr)
|
||||||
|
val fragmentShdrHndl = compileShader(GLES20.GL_FRAGMENT_SHADER, fragmentShdr)
|
||||||
|
|
||||||
|
mHexahedronVertexPrgrmHndl = createAndLinkProgram(vertexShdrHndl, fragmentShdrHndl,
|
||||||
|
arrayOf("a_Position", "a_Color", "a_Normal", "a_TexCoordinate"))
|
||||||
|
|
||||||
|
mTetraVertexPrgrmHndl = createAndLinkProgram(vertexShdrHndl, fragmentShdrHndl,
|
||||||
|
arrayOf("a_Position", "a_Color", "a_Normal"))
|
||||||
|
|
||||||
|
// Definition of shader programs for the source of light
|
||||||
|
val pointVrtxShdr = ShaderSource.getTextFromResourceFile(mActivityContext,
|
||||||
|
R.raw.lignt_point_vertex_shader_code)
|
||||||
|
val pointFragmentShader = ShaderSource.getTextFromResourceFile(mActivityContext,
|
||||||
|
R.raw.lignt_point_fragment_shader_code)
|
||||||
|
|
||||||
|
if (pointVrtxShdr==null || pointFragmentShader==null)
|
||||||
|
{
|
||||||
|
System.exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
val pointVrtxShdrHndl = compileShader(GLES20.GL_VERTEX_SHADER, pointVrtxShdr)
|
||||||
|
val pointFrgmntShdrHndl = compileShader(GLES20.GL_FRAGMENT_SHADER, pointFragmentShader)
|
||||||
|
mLightPointPrgrmHndl = createAndLinkProgram(pointVrtxShdrHndl, pointFrgmntShdrHndl,
|
||||||
|
arrayOf("a_Position"))
|
||||||
|
|
||||||
|
for (i in 0..13) // init of textures array
|
||||||
|
mTextureDataHndls[i] = ShaderSource.readTextureFromResource(mActivityContext, mTextures[i])
|
||||||
|
}
|
||||||
|
|
||||||
|
// change the area of view
|
||||||
|
override fun onSurfaceChanged(glOldVers: GL10, width: Int, height: Int)
|
||||||
|
{
|
||||||
|
// Setting of the OpenGL viewport equal to the size of the screen
|
||||||
|
GLES20.glViewport(0, 0, width, height)
|
||||||
|
|
||||||
|
// Create a new perspective projection matrix
|
||||||
|
// ratio is calculated to take in account real proportions of the screen
|
||||||
|
val ratioSC = width.toFloat() / height
|
||||||
|
val leftSC = -ratioSC
|
||||||
|
val bottomSC = -1.0f
|
||||||
|
val topSC = 1.0f
|
||||||
|
val nearSC = 1.0f
|
||||||
|
val farSC = 14.0f
|
||||||
|
|
||||||
|
// cutting volume
|
||||||
|
Matrix.frustumM(mProjMtrx, 0, leftSC, ratioSC, bottomSC, topSC, nearSC, farSC)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onDrawFrame(glOldVers: GL10)
|
||||||
|
{
|
||||||
|
GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT or GLES20.GL_DEPTH_BUFFER_BIT)
|
||||||
|
|
||||||
|
// calculate rotations for automatic mode (animation here!)
|
||||||
|
if (!mHandleMode) {
|
||||||
|
val time = SystemClock.uptimeMillis() % 10000L
|
||||||
|
mAngleBodies = 360.0f / 10000.0f * time.toInt()
|
||||||
|
//val time2 = SystemClock.uptimeMillis() % 4000L
|
||||||
|
mAngleCenter = 0.09f * time.toInt()
|
||||||
|
}
|
||||||
|
|
||||||
|
setPolyhedronsHandles()
|
||||||
|
setLightHandles()
|
||||||
|
|
||||||
|
GLES20.glActiveTexture(GLES20.GL_TEXTURE0)
|
||||||
|
|
||||||
|
//---------- global rotation ------------------------------
|
||||||
|
Matrix.setIdentityM(mViewMtrx, 0)
|
||||||
|
Matrix.translateM(mViewMtrx, 0, 0.0f, 0.0f, ZObjectsPos.getPosition(0).toFloat())
|
||||||
|
if (!mHadleRotation)
|
||||||
|
// rotation around X-axis
|
||||||
|
Matrix.rotateM(mViewMtrx, 0, mGlobalAngle * 1.0f, 0.0f, 1.0f, 0.0f)
|
||||||
|
else
|
||||||
|
// rotation around Y-axis
|
||||||
|
Matrix.rotateM(mViewMtrx, 0, mGlobalAngle * 1.0f, 1.0f, 0.0f, 0.0f)
|
||||||
|
Matrix.translateM(mViewMtrx, 0, 0.0f, 0.0f, -ZObjectsPos.getPosition(0).toFloat())
|
||||||
|
//==========================================================
|
||||||
|
|
||||||
|
// Draw polyhedrons
|
||||||
|
putRightBody()
|
||||||
|
putLeftBody()
|
||||||
|
putTopBody()
|
||||||
|
putBottomBody()
|
||||||
|
putCentralBody()
|
||||||
|
drawLamp()
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun setPolyhedronsHandles()
|
||||||
|
{
|
||||||
|
// Set program handles for polyhedrons
|
||||||
|
GLES20.glUseProgram(mHexahedronVertexPrgrmHndl)
|
||||||
|
|
||||||
|
mMVPMtrxHndl = GLES20.glGetUniformLocation(mHexahedronVertexPrgrmHndl, "u_MVPMatrix")
|
||||||
|
mMVMtrxHndl = GLES20.glGetUniformLocation(mHexahedronVertexPrgrmHndl, "u_MVMatrix")
|
||||||
|
mLightPsHndl = GLES20.glGetUniformLocation(mHexahedronVertexPrgrmHndl, "u_LightPos")
|
||||||
|
mTextureUniformHndl = GLES20.glGetUniformLocation(mHexahedronPstnHndl, "u_Texture")
|
||||||
|
mHexahedronPstnHndl = GLES20.glGetAttribLocation(mHexahedronVertexPrgrmHndl, "a_Position")
|
||||||
|
mHexahedronClrHndl = GLES20.glGetAttribLocation(mHexahedronVertexPrgrmHndl, "a_Color")
|
||||||
|
mHexahedronNrmlHndl = GLES20.glGetAttribLocation(mHexahedronVertexPrgrmHndl, "a_Normal")
|
||||||
|
mTextureCoordHndl = GLES20.glGetAttribLocation(mHexahedronVertexPrgrmHndl, "a_TexCoordinate")
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun setLightHandles()
|
||||||
|
{
|
||||||
|
// put vertex-lighting program
|
||||||
|
GLES20.glUseProgram(mTetraVertexPrgrmHndl)
|
||||||
|
|
||||||
|
// Set program handles (tetrahedron)
|
||||||
|
mMVPMtrxHndl = GLES20.glGetUniformLocation(mTetraVertexPrgrmHndl, "u_MVPMatrix")
|
||||||
|
mMVMtrxHndl = GLES20.glGetUniformLocation(mTetraVertexPrgrmHndl, "u_MVMatrix")
|
||||||
|
mLightPsHndl = GLES20.glGetUniformLocation(mTetraVertexPrgrmHndl, "u_LightPos")
|
||||||
|
mTetraPstnHndl = GLES20.glGetAttribLocation(mTetraVertexPrgrmHndl, "a_Position")
|
||||||
|
mTetraClrHndl = GLES20.glGetAttribLocation(mTetraVertexPrgrmHndl, "a_Color")
|
||||||
|
mTetraNrmlHndl = GLES20.glGetAttribLocation(mTetraVertexPrgrmHndl, "a_Normal")
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun putRightBody() {
|
||||||
|
// right
|
||||||
|
// binding of the texture
|
||||||
|
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mTextureDataHndls[0])
|
||||||
|
GLES20.glUniform1i(mTextureUniformHndl, 0)
|
||||||
|
|
||||||
|
Matrix.setIdentityM(mModelMtrx, 0)
|
||||||
|
Matrix.translateM(mModelMtrx, 0, 3.0f, 0.0f, ZObjectsPos.getPosition(2).toFloat())
|
||||||
|
Matrix.rotateM(mModelMtrx, 0, mAngleBodies * 1.0f, mRotationVector!![0], mRotationVector!![1], mRotationVector!![2] /*0.0f, 1.0f, 1.0f*/)
|
||||||
|
drawHexahedron()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun putLeftBody()
|
||||||
|
{
|
||||||
|
// left
|
||||||
|
// binding of the texture
|
||||||
|
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mTextureDataHndls[1] /*mTextureDataHandle2*/)
|
||||||
|
GLES20.glUniform1i(mTextureUniformHndl, 0)
|
||||||
|
|
||||||
|
Matrix.setIdentityM(mModelMtrx, 0)
|
||||||
|
Matrix.translateM(mModelMtrx, 0, -3.0f, 0.0f, ZObjectsPos.getPosition(1).toFloat())
|
||||||
|
Matrix.rotateM(mModelMtrx, 0, mAngleBodies * 2f, mRotationVector!![0], mRotationVector!![1], mRotationVector!![2] /*0.0f, 1.0f, 1.0f*/)
|
||||||
|
drawHexahedron()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun putTopBody()
|
||||||
|
{
|
||||||
|
// top
|
||||||
|
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mTextureDataHndls[2] /*mTextureDataHandle3*/)
|
||||||
|
GLES20.glUniform1i(mTextureUniformHndl, 0)
|
||||||
|
|
||||||
|
Matrix.setIdentityM(mModelMtrx, 0)
|
||||||
|
Matrix.translateM(mModelMtrx, 0, 0.0f, 3.0f, ZObjectsPos.getPosition(3).toFloat())
|
||||||
|
Matrix.rotateM(mModelMtrx, 0, mAngleBodies * 2f, mRotationVector!![0], mRotationVector!![1], mRotationVector!![2] /*0.0f, 0.0f, 1.0f*/)
|
||||||
|
drawTetrahedron()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun putBottomBody()
|
||||||
|
{
|
||||||
|
// bottom
|
||||||
|
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mTextureDataHndls[3])
|
||||||
|
GLES20.glUniform1i(mTextureUniformHndl, 0)
|
||||||
|
|
||||||
|
Matrix.setIdentityM(mModelMtrx, 0)
|
||||||
|
Matrix.translateM(mModelMtrx, 0, 0.0f, -3.0f, ZObjectsPos.getPosition(4).toFloat())
|
||||||
|
Matrix.rotateM(mModelMtrx, 0, mAngleBodies * 3f, mRotationVector!![0], mRotationVector!![1], mRotationVector!![2] /*1.0f, 1.5f, 1.0f*/)
|
||||||
|
drawTetrahedron()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun putCentralBody()
|
||||||
|
{
|
||||||
|
// central
|
||||||
|
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mTextureDataHndls[4])
|
||||||
|
GLES20.glUniform1i(mTextureUniformHndl, 0)
|
||||||
|
|
||||||
|
val tmp: FloatArray
|
||||||
|
Matrix.setIdentityM(mModelMtrx, 0)
|
||||||
|
Matrix.translateM(mModelMtrx, 0, 0.0f, 0.0f, ZObjectsPos.getPosition(0).toFloat())
|
||||||
|
Matrix.rotateM(mModelMtrx, 0, 90 + mAngleCenter, 1.0f, 0.0f, 0.0f)
|
||||||
|
drawTetrahedron()
|
||||||
|
|
||||||
|
tmp = mModelMtrx
|
||||||
|
Matrix.scaleM(mModelMtrx, 0, 0.7f, 0.7f, 0.7f)
|
||||||
|
Matrix.rotateM(mModelMtrx, 0, mAngleCenter, 1.0f, 0.0f, 0.0f)
|
||||||
|
mModelMtrx = tmp
|
||||||
|
drawHexahedron()
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Draws a hexahedron
|
||||||
|
private fun drawHexahedron()
|
||||||
|
{
|
||||||
|
// send position data to shader
|
||||||
|
mHexahedronPos!!.position(0)
|
||||||
|
GLES20.glVertexAttribPointer(mHexahedronPstnHndl, mPosDataSize, GLES20.GL_FLOAT, false,
|
||||||
|
0, mHexahedronPos)
|
||||||
|
|
||||||
|
GLES20.glEnableVertexAttribArray(mHexahedronPstnHndl)
|
||||||
|
|
||||||
|
// send color data to shader
|
||||||
|
mHexahedronClrs!!.position(0)
|
||||||
|
GLES20.glVertexAttribPointer(mHexahedronClrHndl, mClrDataSize, GLES20.GL_FLOAT, false,
|
||||||
|
0, mHexahedronClrs)
|
||||||
|
|
||||||
|
GLES20.glEnableVertexAttribArray(mHexahedronClrHndl)
|
||||||
|
|
||||||
|
// send normal vectors data to sender
|
||||||
|
mHexahedronNrmls!!.position(0)
|
||||||
|
GLES20.glVertexAttribPointer(mHexahedronNrmlHndl, mNrmlDataSize, GLES20.GL_FLOAT, false,
|
||||||
|
0, mHexahedronNrmls)
|
||||||
|
|
||||||
|
GLES20.glEnableVertexAttribArray(mHexahedronNrmlHndl)
|
||||||
|
|
||||||
|
// textures -----------------------------
|
||||||
|
mHexahedronTextureCoords!!.position(0)
|
||||||
|
GLES20.glVertexAttribPointer(mTextureCoordHndl,
|
||||||
|
mTextureCoordinateDtSz, GLES20.GL_FLOAT, false,
|
||||||
|
0, mHexahedronTextureCoords)
|
||||||
|
|
||||||
|
GLES20.glEnableVertexAttribArray(mTextureCoordHndl)
|
||||||
|
Matrix.multiplyMM(mMVPMtrx, 0, mViewMtrx, 0, mModelMtrx, 0)
|
||||||
|
|
||||||
|
GLES20.glUniformMatrix4fv(mMVMtrxHndl, 1, false, mMVPMtrx, 0)
|
||||||
|
Matrix.multiplyMM(mMVPMtrx, 0, mProjMtrx, 0, mMVPMtrx, 0)
|
||||||
|
|
||||||
|
// set data in final mtrx
|
||||||
|
GLES20.glUniformMatrix4fv(mMVPMtrxHndl, 1, false, mMVPMtrx, 0)
|
||||||
|
|
||||||
|
|
||||||
|
GLES20.glUniform3f(mLightPsHndl, mLightPosInLookAtCoords[0],
|
||||||
|
mLightPosInLookAtCoords[1], mLightPosInLookAtCoords[2])
|
||||||
|
|
||||||
|
// Draw regular hexahedron
|
||||||
|
GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, 36)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Draws the tetrahedron
|
||||||
|
private fun drawTetrahedron()
|
||||||
|
{
|
||||||
|
// set the position data
|
||||||
|
mTetraPosns!!.position(0)
|
||||||
|
GLES20.glVertexAttribPointer(mTetraPstnHndl, mPosDataSize, GLES20.GL_FLOAT, false,
|
||||||
|
0, mTetraPosns)
|
||||||
|
|
||||||
|
GLES20.glEnableVertexAttribArray(mTetraPstnHndl)
|
||||||
|
|
||||||
|
// send the color data
|
||||||
|
mTetraClrs!!.position(0)
|
||||||
|
GLES20.glVertexAttribPointer(mTetraClrHndl, mClrDataSize, GLES20.GL_FLOAT, false,
|
||||||
|
0, mTetraClrs)
|
||||||
|
|
||||||
|
GLES20.glEnableVertexAttribArray(mTetraClrHndl)
|
||||||
|
|
||||||
|
// set the normal vectors data
|
||||||
|
mTetraNrmls!!.position(0)
|
||||||
|
GLES20.glVertexAttribPointer(mTetraNrmlHndl, mNrmlDataSize, GLES20.GL_FLOAT, false,
|
||||||
|
0, mTetraNrmls)
|
||||||
|
|
||||||
|
GLES20.glEnableVertexAttribArray(mTetraNrmlHndl)
|
||||||
|
Matrix.multiplyMM(mMVPMtrx, 0, mViewMtrx, 0, mModelMtrx, 0)
|
||||||
|
|
||||||
|
// modelview
|
||||||
|
GLES20.glUniformMatrix4fv(mMVMtrxHndl, 1, false, mMVPMtrx, 0)
|
||||||
|
Matrix.multiplyMM(mMVPMtrx, 0, mProjMtrx, 0, mMVPMtrx, 0)
|
||||||
|
|
||||||
|
// final matrix
|
||||||
|
GLES20.glUniformMatrix4fv(mMVPMtrxHndl, 1, false, mMVPMtrx, 0)
|
||||||
|
|
||||||
|
// position of the source of the light in viewer coordinate system
|
||||||
|
GLES20.glUniform3f(mLightPsHndl, mLightPosInLookAtCoords[0],
|
||||||
|
mLightPosInLookAtCoords[1], mLightPosInLookAtCoords[2])
|
||||||
|
|
||||||
|
// Draw
|
||||||
|
GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, 12)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Draws point of light
|
||||||
|
private fun drawLamp()
|
||||||
|
{
|
||||||
|
// Draw a point to show the "lamp"
|
||||||
|
|
||||||
|
Matrix.setIdentityM(mLightMdlMtrx, 0)
|
||||||
|
Matrix.translateM(mLightMdlMtrx, 0, 0.0f, 0.0f, -5.0f)
|
||||||
|
Matrix.rotateM(mLightMdlMtrx, 0, mAngleBodies * 3f, 0.0f, 1.0f, 0.0f)
|
||||||
|
Matrix.translateM(mLightMdlMtrx, 0, 0.0f, 0.0f, 2.0f)
|
||||||
|
Matrix.multiplyMV(mLightPosInWorldCoords, 0, mLightMdlMtrx, 0, mLightPosInModelCoords, 0)
|
||||||
|
Matrix.multiplyMV(mLightPosInLookAtCoords, 0, mViewMtrx, 0, mLightPosInWorldCoords, 0)
|
||||||
|
|
||||||
|
GLES20.glUseProgram(mLightPointPrgrmHndl)
|
||||||
|
|
||||||
|
val pointMVPMtrxHndl = GLES20.glGetUniformLocation(mLightPointPrgrmHndl, "u_MVPMatrix")
|
||||||
|
val pointPstnHndl = GLES20.glGetAttribLocation(mLightPointPrgrmHndl, "a_Position")
|
||||||
|
|
||||||
|
GLES20.glVertexAttrib3f(pointPstnHndl, mLightPosInModelCoords[0], mLightPosInModelCoords[1], mLightPosInModelCoords[2])
|
||||||
|
GLES20.glDisableVertexAttribArray(pointPstnHndl)
|
||||||
|
|
||||||
|
Matrix.multiplyMM(mMVPMtrx, 0, mViewMtrx, 0, mLightMdlMtrx, 0)
|
||||||
|
Matrix.multiplyMM(mMVPMtrx, 0, mProjMtrx, 0, mMVPMtrx, 0)
|
||||||
|
GLES20.glUniformMatrix4fv(pointMVPMtrxHndl, 1, false, mMVPMtrx, 0)
|
||||||
|
|
||||||
|
// set the light
|
||||||
|
GLES20.glDrawArrays(GLES20.GL_POINTS, 0, 1)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// method compiles of the shader
|
||||||
|
private fun compileShader(typeOfShader: Int, sourceOfShader: String?): Int
|
||||||
|
{
|
||||||
|
var shaderHndl = GLES20.glCreateShader(typeOfShader)
|
||||||
|
|
||||||
|
if (shaderHndl != 0)
|
||||||
|
{
|
||||||
|
// set source of shader
|
||||||
|
GLES20.glShaderSource(shaderHndl, sourceOfShader)
|
||||||
|
|
||||||
|
// compilation of the shader
|
||||||
|
GLES20.glCompileShader(shaderHndl)
|
||||||
|
|
||||||
|
// get the result of compilation
|
||||||
|
val compileStatus = IntArray(1)
|
||||||
|
GLES20.glGetShaderiv(shaderHndl, GLES20.GL_COMPILE_STATUS, compileStatus, 0)
|
||||||
|
|
||||||
|
// If the compilation was not success, remove the shaderHndl
|
||||||
|
if (compileStatus[0] == 0)
|
||||||
|
{
|
||||||
|
GLES20.glDeleteShader(shaderHndl)
|
||||||
|
shaderHndl = 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (shaderHndl == 0)
|
||||||
|
{
|
||||||
|
throw RuntimeException("Impossible to compile shader program.")
|
||||||
|
}
|
||||||
|
|
||||||
|
return shaderHndl
|
||||||
|
}
|
||||||
|
|
||||||
|
// compile and link the program
|
||||||
|
private fun createAndLinkProgram(vertexShdrHndl: Int, fragmentShdrHndl: Int,
|
||||||
|
attribs: Array<String>?): Int
|
||||||
|
{
|
||||||
|
var programHndl = GLES20.glCreateProgram()
|
||||||
|
|
||||||
|
if (programHndl != 0)
|
||||||
|
{
|
||||||
|
// binding of the vertex shader to the shader program
|
||||||
|
GLES20.glAttachShader(programHndl, vertexShdrHndl)
|
||||||
|
|
||||||
|
// binding the fragment shader to the shader program
|
||||||
|
GLES20.glAttachShader(programHndl, fragmentShdrHndl)
|
||||||
|
|
||||||
|
// binding of attribs
|
||||||
|
if (attribs != null)
|
||||||
|
{
|
||||||
|
val size = attribs.size
|
||||||
|
for (i in 0 until size)
|
||||||
|
{
|
||||||
|
GLES20.glBindAttribLocation(programHndl, i, attribs[i])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// linking of shaders
|
||||||
|
GLES20.glLinkProgram(programHndl)
|
||||||
|
|
||||||
|
// getting the linkage result
|
||||||
|
val linkResult = IntArray(1)
|
||||||
|
GLES20.glGetProgramiv(programHndl, GLES20.GL_LINK_STATUS, linkResult, 0)
|
||||||
|
|
||||||
|
// if fail
|
||||||
|
if (linkResult[0] == 0)
|
||||||
|
{
|
||||||
|
GLES20.glDeleteProgram(programHndl)
|
||||||
|
programHndl = 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (programHndl == 0)
|
||||||
|
{
|
||||||
|
return 0
|
||||||
|
throw RuntimeException("Impossible to create shader program.")
|
||||||
|
}
|
||||||
|
|
||||||
|
return programHndl
|
||||||
|
}
|
||||||
|
|
||||||
|
var Angle : Float
|
||||||
|
get() = mGlobalAngle
|
||||||
|
set(newvalue)
|
||||||
|
{
|
||||||
|
mGlobalAngle = newvalue
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
fun setRotationDirection()
|
||||||
|
{
|
||||||
|
when (TiltData.getDirection())
|
||||||
|
{
|
||||||
|
TiltDirections.UP ->
|
||||||
|
{
|
||||||
|
mRotationVector = floatArrayOf(-1.0f, 0.0f, 0.0f)
|
||||||
|
mAngleBodies = Math.abs(mAngleBodies)
|
||||||
|
}
|
||||||
|
TiltDirections.DOWN ->
|
||||||
|
{
|
||||||
|
mRotationVector = floatArrayOf(1.0f, 0.0f, 0.0f)
|
||||||
|
mAngleBodies = -Math.abs(mAngleBodies)
|
||||||
|
}
|
||||||
|
TiltDirections.LEFT ->
|
||||||
|
{
|
||||||
|
mRotationVector = floatArrayOf(0.0f, -1.0f, 0.0f)
|
||||||
|
mAngleBodies = Math.abs(mAngleBodies)
|
||||||
|
}
|
||||||
|
TiltDirections.RIGHT ->
|
||||||
|
{
|
||||||
|
mRotationVector = floatArrayOf(0.0f, 1.0f, 0.0f)
|
||||||
|
mAngleBodies = -Math.abs(mAngleBodies)
|
||||||
|
}
|
||||||
|
TiltDirections.UNKNOWN ->
|
||||||
|
{
|
||||||
|
return
|
||||||
|
//mRotationVector = new float[] {0.0f, 0.0f, 1.0f};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun setRotationDirection(voiceCommand : String)
|
||||||
|
{
|
||||||
|
//Log.d("spok",voiceCommand)
|
||||||
|
|
||||||
|
var leftWords = arrayListOf<String>("left", "lift")
|
||||||
|
if (leftWords.contains(voiceCommand))
|
||||||
|
{
|
||||||
|
mRotationVector = floatArrayOf(0.0f, -1.0f, 0.0f)
|
||||||
|
mAngleBodies = Math.abs(mAngleBodies)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if (voiceCommand.contains("right"))
|
||||||
|
{
|
||||||
|
mRotationVector = floatArrayOf(0.0f, 1.0f, 0.0f)
|
||||||
|
mAngleBodies = -Math.abs(mAngleBodies)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
var upWords = arrayListOf<String>("op", "up", "top", "tab")
|
||||||
|
if (upWords.contains(voiceCommand))
|
||||||
|
{
|
||||||
|
mRotationVector = floatArrayOf(-1.0f, 0.0f, 0.0f)
|
||||||
|
mAngleBodies = Math.abs(mAngleBodies)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
var downWords = arrayListOf<String>("dull", "dell", "dong", "dog", "Darwin", "dumb", "gold","done", "dome", "dom", "down","don't","toll", "doll")
|
||||||
|
if (downWords.contains(voiceCommand))
|
||||||
|
{
|
||||||
|
mRotationVector = floatArrayOf(1.0f, 0.0f, 0.0f)
|
||||||
|
mAngleBodies = -Math.abs(mAngleBodies)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun swapTextures()
|
||||||
|
{
|
||||||
|
val tmp = mTextureDataHndls[mTextureDataHndls.size - 1]
|
||||||
|
for (i in mTextureDataHndls.size - 1 downTo 1)
|
||||||
|
{
|
||||||
|
mTextureDataHndls[i] = mTextureDataHndls[i - 1]
|
||||||
|
}
|
||||||
|
mTextureDataHndls[0] = tmp
|
||||||
|
}
|
||||||
|
|
||||||
|
var HadleRotation : Boolean
|
||||||
|
get() = mHadleRotation
|
||||||
|
set(newvalue)
|
||||||
|
{
|
||||||
|
mHadleRotation = newvalue
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
var HandleMode : Boolean
|
||||||
|
get() = mHandleMode
|
||||||
|
set(newvalue)
|
||||||
|
{
|
||||||
|
mHandleMode = newvalue
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,158 @@
|
|||||||
|
package pavelsobolev.kotogl.Space3D
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import android.graphics.PixelFormat
|
||||||
|
import android.opengl.GLES20
|
||||||
|
import android.opengl.GLSurfaceView
|
||||||
|
import android.view.MotionEvent
|
||||||
|
//import pavelsobolev.kotogl.R
|
||||||
|
import sgd.and04.layout.R
|
||||||
|
import sgd.and04.layout.SpaceGLRenderer
|
||||||
|
|
||||||
|
import java.util.*
|
||||||
|
|
||||||
|
/**
|
||||||
|
* represents surface which is capable to be used by OpenGL framework
|
||||||
|
*/
|
||||||
|
class SpaceGLSurface(cntxt: Context, private var mHandleMode: Boolean) : GLSurfaceView(cntxt), Observer
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* renderer for this surface
|
||||||
|
*/
|
||||||
|
private val mSpaceGlRenderer: SpaceGLRenderer
|
||||||
|
|
||||||
|
/**
|
||||||
|
* number which affects the velocity of rotation when touch point
|
||||||
|
* is moving on the screen
|
||||||
|
*/
|
||||||
|
private val SCALE_TOUCH_RATIO = 180.0f / 800
|
||||||
|
|
||||||
|
/**
|
||||||
|
* x-coordinate of previous location of the touch point
|
||||||
|
*/
|
||||||
|
private var mXPrev: Float = 0.toFloat()
|
||||||
|
private var mRotationDirection: Boolean = false
|
||||||
|
|
||||||
|
/**
|
||||||
|
* y-coordinate of previous location of the touch point
|
||||||
|
*/
|
||||||
|
private var mYPrev: Float = 0.toFloat()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
init
|
||||||
|
{
|
||||||
|
setEGLContextClientVersion(2)
|
||||||
|
|
||||||
|
//mTiltData = TiltData(0f, 0f)
|
||||||
|
//TiltData.setData(0f, 0f)
|
||||||
|
mRotationDirection = false //Y is rotational vector
|
||||||
|
|
||||||
|
val images = intArrayOf(
|
||||||
|
R.drawable.marble_12, R.drawable.marble_13,
|
||||||
|
R.drawable.marble_2, R.drawable.marble_10,
|
||||||
|
R.drawable.marble_4, R.drawable.marble_1,
|
||||||
|
R.drawable.marble_3, R.drawable.marble_5,
|
||||||
|
R.drawable.marble_6, R.drawable.marble_7,
|
||||||
|
R.drawable.marble_8, R.drawable.marble_9,
|
||||||
|
R.drawable.marble_11, R.drawable.marble_14)
|
||||||
|
|
||||||
|
setEGLConfigChooser(8, 8, 8, 8, 16, 0);
|
||||||
|
getHolder().setFormat(PixelFormat.RGBA_8888);
|
||||||
|
setZOrderOnTop(true);
|
||||||
|
//mSpaceGlRenderer = SpaceGLRenderer(cntxt, mTiltData, images)
|
||||||
|
mSpaceGlRenderer = SpaceGLRenderer(cntxt, /*TiltData,*/ images)
|
||||||
|
|
||||||
|
mSpaceGlRenderer.HandleMode = mHandleMode
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
setRenderer(mSpaceGlRenderer)
|
||||||
|
|
||||||
|
if (mSpaceGlRenderer.HandleMode)
|
||||||
|
renderMode = GLSurfaceView.RENDERMODE_WHEN_DIRTY
|
||||||
|
else
|
||||||
|
renderMode = GLSurfaceView.RENDERMODE_CONTINUOUSLY
|
||||||
|
}
|
||||||
|
|
||||||
|
var isHandleMode: Boolean
|
||||||
|
get() = mHandleMode
|
||||||
|
set(_handleMode)
|
||||||
|
{
|
||||||
|
mHandleMode = _handleMode
|
||||||
|
mSpaceGlRenderer.HandleMode = mHandleMode
|
||||||
|
|
||||||
|
if (mSpaceGlRenderer.HandleMode)
|
||||||
|
renderMode = GLSurfaceView.RENDERMODE_WHEN_DIRTY
|
||||||
|
else
|
||||||
|
renderMode = GLSurfaceView.RENDERMODE_CONTINUOUSLY
|
||||||
|
|
||||||
|
requestRender()
|
||||||
|
}
|
||||||
|
|
||||||
|
var isRotationDirection: Boolean
|
||||||
|
get() = mRotationDirection
|
||||||
|
set(_mRotationDirection)
|
||||||
|
{
|
||||||
|
mRotationDirection = _mRotationDirection
|
||||||
|
mSpaceGlRenderer.HadleRotation = mRotationDirection
|
||||||
|
requestRender()
|
||||||
|
}
|
||||||
|
|
||||||
|
// handles event when user touch the screen and move finger
|
||||||
|
// on the surface of the screen of the device
|
||||||
|
override fun onTouchEvent(e: MotionEvent): Boolean
|
||||||
|
{
|
||||||
|
//if(!mSpaceGlRenderer.isHandleMode()) return true;
|
||||||
|
|
||||||
|
if (e==null) return false;
|
||||||
|
|
||||||
|
val posx = e.x
|
||||||
|
val posy = e.y
|
||||||
|
|
||||||
|
when (e.action)
|
||||||
|
{
|
||||||
|
MotionEvent.ACTION_MOVE ->
|
||||||
|
{
|
||||||
|
var deltax = posx - mXPrev
|
||||||
|
var deltay = posy - mYPrev
|
||||||
|
|
||||||
|
if (posy > height / 2) deltax = -deltax
|
||||||
|
|
||||||
|
if (posx < width / 2) deltay = -deltay
|
||||||
|
|
||||||
|
mSpaceGlRenderer.Angle = mSpaceGlRenderer.Angle + (deltax + deltay) * SCALE_TOUCH_RATIO
|
||||||
|
requestRender()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mXPrev = posx
|
||||||
|
mYPrev = posy
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
fun updateDistance()
|
||||||
|
{
|
||||||
|
mSpaceGlRenderer.swapTextures()
|
||||||
|
requestRender()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun passSwapTextures()
|
||||||
|
{
|
||||||
|
mSpaceGlRenderer.swapTextures()
|
||||||
|
requestRender()
|
||||||
|
}
|
||||||
|
|
||||||
|
// when information in TiltData global object is changed this object will get notification and
|
||||||
|
// will force the scene renderer to redraw the picture
|
||||||
|
override fun update(observableObject: Observable?, observableData: Any?)
|
||||||
|
{
|
||||||
|
mSpaceGlRenderer.setRotationDirection()
|
||||||
|
requestRender()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun sendVoiceCommandToRenderer(command:String)
|
||||||
|
{
|
||||||
|
mSpaceGlRenderer.setRotationDirection(command)
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,274 @@
|
|||||||
|
package pavelsobolev.kotogl.Space3D
|
||||||
|
|
||||||
|
object VertexSource
|
||||||
|
{
|
||||||
|
// constants for colours and coordinates
|
||||||
|
private val one : Float = 1.0f
|
||||||
|
private val zero : Float = 0.0f
|
||||||
|
private val z8 : Float = 0.7f
|
||||||
|
private val z7 : Float = 0.8f
|
||||||
|
|
||||||
|
// X, Y, Z of hexahedron vertices
|
||||||
|
private val hexahedronCoordinates = floatArrayOf(
|
||||||
|
// Front
|
||||||
|
-one, one, one,
|
||||||
|
-one, -one, one,
|
||||||
|
one, one, one,
|
||||||
|
-one, -one, one,
|
||||||
|
one, -one, one,
|
||||||
|
one, one, one,
|
||||||
|
|
||||||
|
// Right
|
||||||
|
one, one, one,
|
||||||
|
one, -one, one,
|
||||||
|
one, one, -one,
|
||||||
|
one, -one, one,
|
||||||
|
one, -one, -one,
|
||||||
|
one, one, -one,
|
||||||
|
|
||||||
|
// Back
|
||||||
|
one, one, -one,
|
||||||
|
one, -one, -one,
|
||||||
|
-one, one, -one,
|
||||||
|
one, -one, -one,
|
||||||
|
-one, -one, -one,
|
||||||
|
-one, one, -one,
|
||||||
|
|
||||||
|
// Left
|
||||||
|
-one, one, -one,
|
||||||
|
-one, -one, -one,
|
||||||
|
-one, one, one,
|
||||||
|
-one, -one, -one,
|
||||||
|
-one, -one, one,
|
||||||
|
-one, one, one,
|
||||||
|
|
||||||
|
// Top
|
||||||
|
-one, one, -one,
|
||||||
|
-one, one, one,
|
||||||
|
one, one, -one,
|
||||||
|
-one, one, one,
|
||||||
|
one, one, one,
|
||||||
|
one, one, -one,
|
||||||
|
|
||||||
|
// Bottom
|
||||||
|
one, -one, -one,
|
||||||
|
one, -one, one,
|
||||||
|
-one, -one, -one,
|
||||||
|
one, -one, one,
|
||||||
|
-one, -one, one,
|
||||||
|
-one, -one, -one)
|
||||||
|
|
||||||
|
// R, G, B, A of hexahedron vertices
|
||||||
|
private val hexahedronColors = floatArrayOf(
|
||||||
|
// Front color
|
||||||
|
z8, z8, z8, one,
|
||||||
|
z8, z8, z8, one,
|
||||||
|
z8, z8, z8, one,
|
||||||
|
z8, z8, z8, one,
|
||||||
|
z8, z8, z8, one,
|
||||||
|
z8, z8, z8, one,
|
||||||
|
|
||||||
|
// Right color
|
||||||
|
z8, z8, z8, one,
|
||||||
|
z8, z8, z8, one,
|
||||||
|
z8, z8, z8, one,
|
||||||
|
z8, z8, z8, one,
|
||||||
|
z8, z8, z8, one,
|
||||||
|
z8, z8, z8, one,
|
||||||
|
|
||||||
|
// Back color
|
||||||
|
z8, z8, z8, one,
|
||||||
|
z8, z8, z8, one,
|
||||||
|
z8, z8, z8, one,
|
||||||
|
z8, z8, z8, one,
|
||||||
|
z8, z8, z8, one,
|
||||||
|
z8, z8, z8, one,
|
||||||
|
|
||||||
|
// Left color
|
||||||
|
z8, z8, z8, one,
|
||||||
|
z8, z8, z8, one,
|
||||||
|
z8, z8, z8, one,
|
||||||
|
z8, z8, z8, one,
|
||||||
|
z8, z8, z8, one,
|
||||||
|
z8, z8, z8, one,
|
||||||
|
|
||||||
|
// Top color
|
||||||
|
z8, z8, z8, one,
|
||||||
|
z8, z8, z8, one,
|
||||||
|
z8, z8, z8, one,
|
||||||
|
z8, z8, z8, one,
|
||||||
|
z8, z8, z8, one,
|
||||||
|
z8, z8, z8, one,
|
||||||
|
|
||||||
|
// Bottom color
|
||||||
|
z8, z8, z8, one,
|
||||||
|
z8, z8, z8, one,
|
||||||
|
z8, z8, z8, one,
|
||||||
|
z8, z8, z8, one,
|
||||||
|
z8, z8, z8, one,
|
||||||
|
z8, z8, z8, one)
|
||||||
|
|
||||||
|
// X, Y, Z
|
||||||
|
private val hexahedronNormalVectors = floatArrayOf(
|
||||||
|
// Front face
|
||||||
|
zero, zero, one,
|
||||||
|
zero, zero, one,
|
||||||
|
zero, zero, one,
|
||||||
|
zero, zero, one,
|
||||||
|
zero, zero, one,
|
||||||
|
zero, zero, one,
|
||||||
|
|
||||||
|
// Right face
|
||||||
|
one, zero, zero,
|
||||||
|
one, zero, zero,
|
||||||
|
one, zero, zero,
|
||||||
|
one, zero, zero,
|
||||||
|
one, zero, zero,
|
||||||
|
one, zero, zero,
|
||||||
|
|
||||||
|
// Back face
|
||||||
|
zero, zero, -one,
|
||||||
|
zero, zero, -one,
|
||||||
|
zero, zero, -one,
|
||||||
|
zero, zero, -one,
|
||||||
|
zero, zero, -one,
|
||||||
|
zero, zero, -one,
|
||||||
|
|
||||||
|
// Left face
|
||||||
|
-one, zero, zero,
|
||||||
|
-one, zero, zero,
|
||||||
|
-one, zero, zero,
|
||||||
|
-one, zero, zero,
|
||||||
|
-one, zero, zero,
|
||||||
|
-one, zero, zero,
|
||||||
|
|
||||||
|
// Top face
|
||||||
|
zero, one, zero,
|
||||||
|
zero, one, zero,
|
||||||
|
zero, one, zero,
|
||||||
|
zero, one, zero,
|
||||||
|
zero, one, zero,
|
||||||
|
zero, one, zero,
|
||||||
|
|
||||||
|
// Bottom face
|
||||||
|
zero, -one, zero,
|
||||||
|
zero, -one, zero,
|
||||||
|
zero, -one, zero,
|
||||||
|
zero, -one, zero,
|
||||||
|
zero, -one, zero,
|
||||||
|
zero, -one, zero)
|
||||||
|
|
||||||
|
private val hexahedronTextureCoordinateData = floatArrayOf(
|
||||||
|
// Front face
|
||||||
|
zero, zero, zero,
|
||||||
|
one, one, zero,
|
||||||
|
zero, one, one,
|
||||||
|
one, one, zero,
|
||||||
|
|
||||||
|
// Right face
|
||||||
|
zero, zero, zero,
|
||||||
|
one, one, zero,
|
||||||
|
zero, one, one,
|
||||||
|
one, one, zero,
|
||||||
|
|
||||||
|
// Back face
|
||||||
|
zero, zero, zero,
|
||||||
|
one, one, zero,
|
||||||
|
zero, one, one,
|
||||||
|
one, one, zero,
|
||||||
|
|
||||||
|
// Left face
|
||||||
|
zero, zero, zero,
|
||||||
|
one, one, zero,
|
||||||
|
zero, one, one,
|
||||||
|
one, one, zero,
|
||||||
|
|
||||||
|
// Top face
|
||||||
|
zero, zero, zero,
|
||||||
|
one, one, zero,
|
||||||
|
zero, one, one,
|
||||||
|
one, one, zero,
|
||||||
|
|
||||||
|
// Bottom face
|
||||||
|
zero, zero, zero,
|
||||||
|
one, one, zero,
|
||||||
|
zero, one, one,
|
||||||
|
one, one, zero)
|
||||||
|
|
||||||
|
// tetrahedron data
|
||||||
|
|
||||||
|
private val tetrahedronCoordinates = floatArrayOf(
|
||||||
|
-one, one, one,
|
||||||
|
-one, -one, -one,
|
||||||
|
one, -one, one,
|
||||||
|
|
||||||
|
one, -one, one,
|
||||||
|
-one, -one, -one,
|
||||||
|
one, one, -one,
|
||||||
|
|
||||||
|
one, one, -one,
|
||||||
|
-one, -one, -one,
|
||||||
|
-one, one, one,
|
||||||
|
|
||||||
|
-one, one, one,
|
||||||
|
one, -one, one,
|
||||||
|
one, one, -one)
|
||||||
|
|
||||||
|
private val tetrahedronColors = floatArrayOf(
|
||||||
|
z7, z7, z7, one,
|
||||||
|
z7, z7, z7, one,
|
||||||
|
z7, z7, z7, one,
|
||||||
|
|
||||||
|
z7, z7, z7, one,
|
||||||
|
z7, z7, z7, one,
|
||||||
|
z7, z7, z7, one,
|
||||||
|
|
||||||
|
z7, z7, z7, one,
|
||||||
|
z7, z7, z7, one,
|
||||||
|
z7, z7, z7, one,
|
||||||
|
|
||||||
|
z7, z7, z7, one,
|
||||||
|
z7, z7, z7, one,
|
||||||
|
z7, z7, z7, one)
|
||||||
|
|
||||||
|
private val tetrahedronNormalVectors = floatArrayOf(
|
||||||
|
-one, -one, one,
|
||||||
|
-one, -one, one,
|
||||||
|
-one, -one, one,
|
||||||
|
|
||||||
|
one, -one, -one,
|
||||||
|
one, -one, -one,
|
||||||
|
one, -one, -one,
|
||||||
|
|
||||||
|
-one, one, -one,
|
||||||
|
-one, one, -one,
|
||||||
|
-one, one, -one,
|
||||||
|
|
||||||
|
one, one, one,
|
||||||
|
one, one, one,
|
||||||
|
one, one, one)
|
||||||
|
|
||||||
|
|
||||||
|
// --- public getters
|
||||||
|
|
||||||
|
val HexahedronCoordinates : FloatArray
|
||||||
|
get() = this.hexahedronCoordinates
|
||||||
|
|
||||||
|
val HexahedronColors: FloatArray
|
||||||
|
get() = hexahedronColors
|
||||||
|
|
||||||
|
val HexahedronNormalVectors: FloatArray
|
||||||
|
get() = hexahedronNormalVectors
|
||||||
|
|
||||||
|
val TetrahedronCoordinates: FloatArray
|
||||||
|
get() = tetrahedronCoordinates
|
||||||
|
|
||||||
|
val TetrahedronColors: FloatArray
|
||||||
|
get() = tetrahedronColors
|
||||||
|
|
||||||
|
val TetrahedronNormalVectors: FloatArray
|
||||||
|
get() = tetrahedronNormalVectors
|
||||||
|
|
||||||
|
val HexahedronTextureCoordinateData: FloatArray
|
||||||
|
get() = hexahedronTextureCoordinateData
|
||||||
|
}
|
@ -0,0 +1,178 @@
|
|||||||
|
package pavelsobolev.kotogl.Spiral2D
|
||||||
|
|
||||||
|
import android.opengl.GLES20
|
||||||
|
import android.opengl.GLSurfaceView
|
||||||
|
import android.opengl.Matrix
|
||||||
|
import android.os.SystemClock
|
||||||
|
import javax.microedition.khronos.opengles.GL10
|
||||||
|
|
||||||
|
// 2D renderer - shows the spiral, the square and the triangle
|
||||||
|
// using OpenGL
|
||||||
|
class MyGLRenderer : GLSurfaceView.Renderer
|
||||||
|
{
|
||||||
|
internal var mW = 0
|
||||||
|
internal var mH = 0
|
||||||
|
|
||||||
|
var mIsHandleMode: Boolean = false
|
||||||
|
|
||||||
|
//@Volatile
|
||||||
|
var mAngle: Float = 0.toFloat()
|
||||||
|
private var mRotatDir: Float = 0.toFloat()
|
||||||
|
|
||||||
|
private var mTriangle: Triangle? = null
|
||||||
|
private var mSquare: Square? = null
|
||||||
|
private var mSpiral: Spiral? = null
|
||||||
|
|
||||||
|
private var mCrrntPointSquare = 0
|
||||||
|
private var mCrrntPointSquareUp = true
|
||||||
|
|
||||||
|
private var mCrrntPointTri = 0
|
||||||
|
private var mCrrntPointTriUp = true
|
||||||
|
|
||||||
|
private val mMtrxMVP = FloatArray(16) // model-view-projection matrix
|
||||||
|
private val mMtrxProjection = FloatArray(16)
|
||||||
|
private val mMtrxView = FloatArray(16)
|
||||||
|
private val mMtrxRotation = FloatArray(16)
|
||||||
|
//private val mTranslationMatrix = FloatArray(16)
|
||||||
|
|
||||||
|
override fun onSurfaceCreated(gl10: GL10, eglConfig: javax.microedition.khronos.egl.EGLConfig)
|
||||||
|
{
|
||||||
|
mAngle = 0.0f
|
||||||
|
mRotatDir = 1f
|
||||||
|
GLES20.glClearColor(0.0f, 0.0f, 0.0f, .5f)
|
||||||
|
mTriangle = Triangle()
|
||||||
|
mSquare = Square()
|
||||||
|
mSpiral = Spiral()
|
||||||
|
mCrrntPointSquare = 0
|
||||||
|
mCrrntPointSquareUp = true
|
||||||
|
|
||||||
|
mCrrntPointTri = mSpiral!!.getSpiralVirtices().size - 7
|
||||||
|
mCrrntPointSquareUp = false
|
||||||
|
}
|
||||||
|
|
||||||
|
var Angle : Float
|
||||||
|
get() = mAngle
|
||||||
|
set(newVal)
|
||||||
|
{
|
||||||
|
mAngle = newVal
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onDrawFrame(unused: GL10)
|
||||||
|
{
|
||||||
|
val localMtrx = FloatArray(16)
|
||||||
|
GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT)
|
||||||
|
|
||||||
|
if (!mIsHandleMode)
|
||||||
|
{
|
||||||
|
val time = SystemClock.uptimeMillis() % 40000L
|
||||||
|
mAngle = 0.009f * time.toInt()
|
||||||
|
}
|
||||||
|
|
||||||
|
val eyeX = 0.0f
|
||||||
|
val eyeY = 0.0f
|
||||||
|
val eyeZ = 1.5f
|
||||||
|
|
||||||
|
val lookX = 0.0f
|
||||||
|
val lookY = 0.0f
|
||||||
|
val lookZ = 0.0f
|
||||||
|
|
||||||
|
val upX = 0.0f
|
||||||
|
val upY = 1.0f
|
||||||
|
val upZ = 0.0f
|
||||||
|
|
||||||
|
Matrix.setLookAtM(mMtrxView, 0, eyeX, eyeY, eyeZ, lookX, lookY, lookZ, upX, upY, upZ)
|
||||||
|
Matrix.multiplyMM(mMtrxMVP, 0, mMtrxProjection, 0, mMtrxView, 0)
|
||||||
|
|
||||||
|
Matrix.setIdentityM(localMtrx, 0)
|
||||||
|
Matrix.setRotateM(mMtrxRotation, 0, mRotatDir * mAngle, 0.0f, 0.0f, 1.0f)
|
||||||
|
Matrix.multiplyMM(localMtrx, 0, mMtrxMVP, 0, mMtrxRotation, 0)
|
||||||
|
|
||||||
|
mSpiral!!.draw(localMtrx)
|
||||||
|
|
||||||
|
mSquare!!.draw(localMtrx,
|
||||||
|
mSpiral!!.getSpiralVirtices()[mCrrntPointSquare],
|
||||||
|
mSpiral!!.getSpiralVirtices()[mCrrntPointSquare + 1],
|
||||||
|
mSpiral!!.getSpiralVirtices()[mCrrntPointSquare + 2])
|
||||||
|
|
||||||
|
if (mCrrntPointSquareUp)
|
||||||
|
{
|
||||||
|
if (mCrrntPointSquare < mSpiral!!.getSpiralVirtices().size - 7)
|
||||||
|
mCrrntPointSquare += 7
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mCrrntPointSquareUp = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (mCrrntPointSquare > 0)
|
||||||
|
{
|
||||||
|
mCrrntPointSquare -= 7
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mCrrntPointSquareUp = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mTriangle!!.draw(localMtrx,
|
||||||
|
mSpiral!!.getSpiralVirtices()[mCrrntPointTri],
|
||||||
|
mSpiral!!.getSpiralVirtices()[mCrrntPointTri + 1],
|
||||||
|
mSpiral!!.getSpiralVirtices()[mCrrntPointTri + 2])
|
||||||
|
|
||||||
|
if (mCrrntPointTriUp)
|
||||||
|
{
|
||||||
|
if (mCrrntPointTri < mSpiral!!.getSpiralVirtices().size - 7)
|
||||||
|
mCrrntPointTri += 7
|
||||||
|
else
|
||||||
|
mCrrntPointTriUp = false
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (mCrrntPointTri > 0)
|
||||||
|
mCrrntPointTri -= 7
|
||||||
|
else
|
||||||
|
mCrrntPointTriUp = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
var CurrentSquareDirection : Boolean
|
||||||
|
get() = mCrrntPointSquareUp
|
||||||
|
set(newDirect)
|
||||||
|
{
|
||||||
|
mCrrntPointSquareUp = newDirect
|
||||||
|
}
|
||||||
|
|
||||||
|
var CurrentTriangleDirection : Boolean
|
||||||
|
get() = mCrrntPointTriUp
|
||||||
|
set(newDirect)
|
||||||
|
{
|
||||||
|
mCrrntPointTriUp = newDirect
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onSurfaceChanged(gl: GL10, width: Int, height: Int)
|
||||||
|
{
|
||||||
|
GLES20.glViewport(0, 0, width, height)
|
||||||
|
val ratio = width.toFloat() / height
|
||||||
|
//Matrix.perspectiveM(mMtrxProjection,);
|
||||||
|
val left = -ratio
|
||||||
|
val bottom = -1.0f
|
||||||
|
val top = 1.0f
|
||||||
|
val near = 1.0f
|
||||||
|
val far = 10.0f
|
||||||
|
Matrix.frustumM(mMtrxProjection, 0, left, ratio, bottom, top, near, far)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object
|
||||||
|
{
|
||||||
|
fun loadShader(type: Int, shaderCode: String): Int
|
||||||
|
{
|
||||||
|
val shader = GLES20.glCreateShader(type)
|
||||||
|
GLES20.glShaderSource(shader, shaderCode)
|
||||||
|
GLES20.glCompileShader(shader)
|
||||||
|
return shader
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,101 @@
|
|||||||
|
package pavelsobolev.kotogl.Spiral2D
|
||||||
|
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import android.graphics.PixelFormat
|
||||||
|
import android.opengl.GLSurfaceView
|
||||||
|
import android.util.Log.wtf
|
||||||
|
import android.view.MotionEvent
|
||||||
|
import pavelsobolev.kotogl.Helpers.TiltData
|
||||||
|
import pavelsobolev.kotogl.Helpers.TiltDirections
|
||||||
|
import java.util.*
|
||||||
|
|
||||||
|
// view for rendering the 2D scene - for embedding into the activity
|
||||||
|
class MyGLSurfaceView(context: Context) : GLSurfaceView(context), Observer
|
||||||
|
{
|
||||||
|
private val myGLRenderer: MyGLRenderer
|
||||||
|
private val TOUCH_SCALE_RATIO = 180.0f / 400
|
||||||
|
private var mPrevX: Float = 0.toFloat()
|
||||||
|
private var mPrevY: Float = 0.toFloat()
|
||||||
|
|
||||||
|
init
|
||||||
|
{
|
||||||
|
setEGLContextClientVersion(2)
|
||||||
|
setEGLConfigChooser(8, 8, 8, 8, 16, 0);
|
||||||
|
getHolder().setFormat(PixelFormat.TRANSPARENT);
|
||||||
|
setZOrderOnTop(true);
|
||||||
|
|
||||||
|
myGLRenderer = MyGLRenderer()
|
||||||
|
|
||||||
|
setRenderer(myGLRenderer)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onTouchEvent(motiEvent: MotionEvent): Boolean
|
||||||
|
{
|
||||||
|
val posx = motiEvent.x
|
||||||
|
val posy = motiEvent.y
|
||||||
|
|
||||||
|
when (motiEvent.action)
|
||||||
|
{
|
||||||
|
MotionEvent.ACTION_MOVE ->
|
||||||
|
{
|
||||||
|
var deltaX = posx - mPrevX
|
||||||
|
var deltaY = posy - mPrevY
|
||||||
|
|
||||||
|
if (posy > height / 2)
|
||||||
|
{
|
||||||
|
deltaX = -deltaX
|
||||||
|
}
|
||||||
|
|
||||||
|
if (x < width / 2)
|
||||||
|
{
|
||||||
|
deltaY = -deltaY
|
||||||
|
}
|
||||||
|
|
||||||
|
myGLRenderer.Angle = (myGLRenderer.Angle + (deltaX + deltaY) * TOUCH_SCALE_RATIO)
|
||||||
|
requestRender()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mPrevX = posx
|
||||||
|
mPrevY = posy
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// when information in TiltData global object is changed this object will get notification and
|
||||||
|
// will force the scene renderer to redraw the picture
|
||||||
|
override fun update(observableObject: Observable?, observableData: Any?)
|
||||||
|
{
|
||||||
|
when (TiltData.getDirection())
|
||||||
|
{
|
||||||
|
TiltDirections.UP -> myGLRenderer.CurrentSquareDirection = true
|
||||||
|
TiltDirections.DOWN -> myGLRenderer.CurrentSquareDirection = false
|
||||||
|
TiltDirections.LEFT -> myGLRenderer.CurrentTriangleDirection = true
|
||||||
|
TiltDirections.RIGHT -> myGLRenderer.CurrentTriangleDirection = false
|
||||||
|
|
||||||
|
else -> wtf("tiltdata", "Cannot start renderer")
|
||||||
|
}
|
||||||
|
requestRender()
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
fun sendVoiceCommandData(voiceCommand: String)
|
||||||
|
{
|
||||||
|
var squareWords = arrayListOf<String>("square", "four", "for")
|
||||||
|
if (squareWords.contains(voiceCommand))
|
||||||
|
{
|
||||||
|
myGLRenderer.CurrentSquareDirection = !myGLRenderer.CurrentSquareDirection
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
var triangleWords = arrayListOf<String>("triangle", "three", "tree", "free")
|
||||||
|
if (triangleWords.contains(voiceCommand))
|
||||||
|
{
|
||||||
|
myGLRenderer.CurrentTriangleDirection = !myGLRenderer.CurrentTriangleDirection
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
requestRender()
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,148 @@
|
|||||||
|
package pavelsobolev.kotogl.Spiral2D
|
||||||
|
|
||||||
|
import android.opengl.GLES10.GL_LINE_SMOOTH
|
||||||
|
import android.opengl.GLES20
|
||||||
|
import java.nio.ByteBuffer
|
||||||
|
import java.nio.ByteOrder
|
||||||
|
import java.nio.FloatBuffer
|
||||||
|
|
||||||
|
class Spiral
|
||||||
|
{
|
||||||
|
internal val COORDS_IN_VERTEX = 7
|
||||||
|
|
||||||
|
private val mVrtxBffr: FloatBuffer
|
||||||
|
private val mFloatSize = 4
|
||||||
|
private val mCntPoint = 360 * 6
|
||||||
|
|
||||||
|
val mSpiralVirtices = FloatArray(mCntPoint * COORDS_IN_VERTEX)
|
||||||
|
|
||||||
|
private var mIncrementalRadius = 0.0f
|
||||||
|
private var mSpiralSpan = 0.003f
|
||||||
|
|
||||||
|
private var mUp = true
|
||||||
|
|
||||||
|
private val mClrOffset = 3
|
||||||
|
|
||||||
|
/** Size of the position data in elements. */
|
||||||
|
private val mPstnDataSize = 3
|
||||||
|
|
||||||
|
/** Size of the color data in elements. */
|
||||||
|
private val mClrDataSize = 4
|
||||||
|
|
||||||
|
private val mVrtxShaderCode = "uniform mat4 uMVPMatrix;" +
|
||||||
|
"attribute vec4 a_Position;" +
|
||||||
|
"attribute vec4 a_Color;" +
|
||||||
|
"varying vec4 v_Color;" +
|
||||||
|
"void main() {" +
|
||||||
|
" v_Color = a_Color;" +
|
||||||
|
" gl_Position = uMVPMatrix * a_Position;" +
|
||||||
|
"}"
|
||||||
|
private val mFrgmntShaderCode = "precision mediump float;" +
|
||||||
|
"varying vec4 v_Color;" +
|
||||||
|
"void main() {" +
|
||||||
|
" gl_FragColor = v_Color;" +
|
||||||
|
"}"
|
||||||
|
|
||||||
|
private val mSdrProgram: Int
|
||||||
|
|
||||||
|
private var mPstnHandle: Int = 0
|
||||||
|
private var mClrHandle: Int = 0
|
||||||
|
private var mMVPMtrxHandle: Int = 0
|
||||||
|
|
||||||
|
private val mVrtxCount = mSpiralVirtices.size / COORDS_IN_VERTEX
|
||||||
|
private val mVrtxStride = COORDS_IN_VERTEX * 4 // 4 bytes per vertex
|
||||||
|
|
||||||
|
init // constructor
|
||||||
|
{
|
||||||
|
GLES20.glLineWidth(15f)
|
||||||
|
|
||||||
|
|
||||||
|
mIncrementalRadius = 0.0f
|
||||||
|
mSpiralSpan = 0.00042f
|
||||||
|
|
||||||
|
var angl = 0.0f //helper vars
|
||||||
|
var color = 0.0f
|
||||||
|
var i = 0
|
||||||
|
|
||||||
|
|
||||||
|
// circle for constructing of spiral
|
||||||
|
while (i < mCntPoint * COORDS_IN_VERTEX)
|
||||||
|
{
|
||||||
|
// position
|
||||||
|
mSpiralVirtices[i] = mIncrementalRadius * Math.sin(angl.toDouble()).toFloat()
|
||||||
|
mSpiralVirtices[i + 1] = mIncrementalRadius * Math.cos(angl.toDouble()).toFloat()
|
||||||
|
mSpiralVirtices[i + 2] = 0.0f
|
||||||
|
// color
|
||||||
|
mSpiralVirtices[i + 3] = color
|
||||||
|
mSpiralVirtices[i + 4] = Math.cos(color.toDouble()).toFloat()
|
||||||
|
mSpiralVirtices[i + 5] = Math.sin(color.toDouble()).toFloat()
|
||||||
|
mSpiralVirtices[i + 6] = 1.0f
|
||||||
|
angl += (Math.PI / 180.0).toFloat()
|
||||||
|
mIncrementalRadius += mSpiralSpan
|
||||||
|
|
||||||
|
if (mUp)
|
||||||
|
color += 0.1f
|
||||||
|
else
|
||||||
|
color -= 0.1f
|
||||||
|
|
||||||
|
if (color == 1f)
|
||||||
|
mUp = false
|
||||||
|
if (color == 0f)
|
||||||
|
mUp = true
|
||||||
|
i += COORDS_IN_VERTEX
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// construction of buffer
|
||||||
|
val bb = ByteBuffer.allocateDirect(mSpiralVirtices.size * mFloatSize)
|
||||||
|
bb.order(ByteOrder.nativeOrder())
|
||||||
|
mVrtxBffr = bb.asFloatBuffer()
|
||||||
|
mVrtxBffr.put(mSpiralVirtices)
|
||||||
|
mVrtxBffr.position(0)
|
||||||
|
|
||||||
|
val vertexShader = MyGLRenderer.loadShader(GLES20.GL_VERTEX_SHADER,
|
||||||
|
mVrtxShaderCode)
|
||||||
|
val fragmentShader = MyGLRenderer.loadShader(GLES20.GL_FRAGMENT_SHADER,
|
||||||
|
mFrgmntShaderCode)
|
||||||
|
|
||||||
|
mSdrProgram = GLES20.glCreateProgram()
|
||||||
|
GLES20.glAttachShader(mSdrProgram, vertexShader)
|
||||||
|
GLES20.glAttachShader(mSdrProgram, fragmentShader)
|
||||||
|
GLES20.glBindAttribLocation(mSdrProgram, 0, "a_Position")
|
||||||
|
GLES20.glBindAttribLocation(mSdrProgram, 1, "a_Color")
|
||||||
|
GLES20.glLinkProgram(mSdrProgram)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getSpiralVirtices(): FloatArray {
|
||||||
|
return mSpiralVirtices
|
||||||
|
}
|
||||||
|
|
||||||
|
fun draw(mvpMatrix: FloatArray)
|
||||||
|
{
|
||||||
|
GLES20.glUseProgram(mSdrProgram)
|
||||||
|
|
||||||
|
mPstnHandle = GLES20.glGetAttribLocation(mSdrProgram, "a_Position")
|
||||||
|
|
||||||
|
mVrtxBffr.position(0)
|
||||||
|
GLES20.glVertexAttribPointer(mPstnHandle, mPstnDataSize,
|
||||||
|
GLES20.GL_FLOAT, false,
|
||||||
|
mVrtxStride, mVrtxBffr)
|
||||||
|
GLES20.glEnableVertexAttribArray(mPstnHandle)
|
||||||
|
|
||||||
|
|
||||||
|
mClrHandle = GLES20.glGetAttribLocation(mSdrProgram, "a_Color")
|
||||||
|
mVrtxBffr.position(mClrOffset)
|
||||||
|
GLES20.glVertexAttribPointer(mClrHandle, mClrDataSize, GLES20.GL_FLOAT, false,
|
||||||
|
mVrtxStride, mVrtxBffr)
|
||||||
|
GLES20.glEnableVertexAttribArray(mClrHandle)
|
||||||
|
|
||||||
|
mMVPMtrxHandle = GLES20.glGetUniformLocation(mSdrProgram, "uMVPMatrix")
|
||||||
|
GLES20.glUniformMatrix4fv(mMVPMtrxHandle, 1, false, mvpMatrix, 0)
|
||||||
|
GLES20.glEnable(GL_LINE_SMOOTH)
|
||||||
|
|
||||||
|
GLES20.glDrawArrays(GLES20.GL_LINE_LOOP, 0, mVrtxCount)
|
||||||
|
|
||||||
|
GLES20.glDisableVertexAttribArray(mPstnHandle)
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,117 @@
|
|||||||
|
package pavelsobolev.kotogl.Spiral2D
|
||||||
|
|
||||||
|
import android.opengl.GLES20
|
||||||
|
import java.nio.ByteBuffer
|
||||||
|
import java.nio.ByteOrder
|
||||||
|
import java.nio.FloatBuffer
|
||||||
|
import java.nio.ShortBuffer
|
||||||
|
|
||||||
|
class Square
|
||||||
|
{
|
||||||
|
internal val CRDS_IN_VERTEX = 3
|
||||||
|
internal var squareCoords = floatArrayOf(-0.15f, 0.15f, 0.15f, // top left
|
||||||
|
-0.15f, -0.15f, 0.15f, // bottom left
|
||||||
|
0.15f, -0.15f, 0.15f, // bottom right
|
||||||
|
0.15f, 0.15f, 0.15f) // top right
|
||||||
|
|
||||||
|
private var mVrtxBuffer: FloatBuffer? = null
|
||||||
|
private val mDrawListBuffer: ShortBuffer
|
||||||
|
|
||||||
|
private val mOrderOfDraw = shortArrayOf(0, 1, 2, 0, 2, 3)
|
||||||
|
private val mGlobalColor = floatArrayOf(1.0f, 0.0f, 0.0f, 0.0f)
|
||||||
|
private val mColorIncrement = floatArrayOf(0.05f, 0.001f, 0.025f, 0.001f)
|
||||||
|
private val mColorUp = booleanArrayOf(false, true, true, true)
|
||||||
|
|
||||||
|
private val mVrtxShaderCode = "uniform mat4 uMVPMatrix;" +
|
||||||
|
"attribute vec4 vPosition;" +
|
||||||
|
"void main() {" +
|
||||||
|
" gl_Position = uMVPMatrix * vPosition;" +
|
||||||
|
"}"
|
||||||
|
private val mFrgmntShaderCode = "precision mediump float;" +
|
||||||
|
"uniform vec4 vColor;" +
|
||||||
|
"void main() {" +
|
||||||
|
" gl_FragColor = vColor;" +
|
||||||
|
"}"
|
||||||
|
|
||||||
|
private val mShaderProgram: Int
|
||||||
|
|
||||||
|
private var mPstnHandle: Int = 0
|
||||||
|
private var mClrHadle: Int = 0
|
||||||
|
private var mMVPMtrxHandle: Int = 0
|
||||||
|
|
||||||
|
private val mVrtxCount = squareCoords.size / CRDS_IN_VERTEX
|
||||||
|
private val mVrtxStride = CRDS_IN_VERTEX * 4
|
||||||
|
|
||||||
|
init
|
||||||
|
{
|
||||||
|
val dlb = ByteBuffer.allocateDirect(mOrderOfDraw.size * 2)
|
||||||
|
dlb.order(ByteOrder.nativeOrder())
|
||||||
|
mDrawListBuffer = dlb.asShortBuffer()
|
||||||
|
mDrawListBuffer.put(mOrderOfDraw)
|
||||||
|
mDrawListBuffer.position(0)
|
||||||
|
|
||||||
|
val vrtxShader = MyGLRenderer.loadShader(GLES20.GL_VERTEX_SHADER,
|
||||||
|
mVrtxShaderCode)
|
||||||
|
val frgmntShader = MyGLRenderer.loadShader(GLES20.GL_FRAGMENT_SHADER,
|
||||||
|
mFrgmntShaderCode)
|
||||||
|
|
||||||
|
mShaderProgram = GLES20.glCreateProgram()
|
||||||
|
GLES20.glAttachShader(mShaderProgram, vrtxShader)
|
||||||
|
GLES20.glAttachShader(mShaderProgram, frgmntShader)
|
||||||
|
GLES20.glLinkProgram(mShaderProgram)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun draw(mvpMtrx: FloatArray, x: Float, y: Float, z: Float)
|
||||||
|
{
|
||||||
|
squareCoords = floatArrayOf(
|
||||||
|
x - 0.05f, y + 0.05f, z,
|
||||||
|
x - 0.05f, y - 0.05f, z,
|
||||||
|
x + 0.05f, y - 0.05f, z,
|
||||||
|
x + 0.05f, y + 0.05f, z)
|
||||||
|
|
||||||
|
val bb = ByteBuffer.allocateDirect(squareCoords.size * 4)
|
||||||
|
bb.order(ByteOrder.nativeOrder())
|
||||||
|
mVrtxBuffer = bb.asFloatBuffer()
|
||||||
|
mVrtxBuffer!!.put(squareCoords)
|
||||||
|
mVrtxBuffer!!.position(0)
|
||||||
|
|
||||||
|
GLES20.glUseProgram(mShaderProgram)
|
||||||
|
|
||||||
|
mPstnHandle = GLES20.glGetAttribLocation(mShaderProgram, "vPosition")
|
||||||
|
GLES20.glEnableVertexAttribArray(mPstnHandle)
|
||||||
|
|
||||||
|
GLES20.glEnableVertexAttribArray(mPstnHandle)
|
||||||
|
GLES20.glVertexAttribPointer(mPstnHandle, CRDS_IN_VERTEX,
|
||||||
|
GLES20.GL_FLOAT, false, mVrtxStride, mVrtxBuffer)
|
||||||
|
|
||||||
|
mClrHadle = GLES20.glGetUniformLocation(mShaderProgram, "vColor")
|
||||||
|
loopColor()
|
||||||
|
GLES20.glUniform4fv(mClrHadle, 1, mGlobalColor, 0)
|
||||||
|
|
||||||
|
mMVPMtrxHandle = GLES20.glGetUniformLocation(mShaderProgram, "uMVPMatrix")
|
||||||
|
GLES20.glUniformMatrix4fv(mMVPMtrxHandle, 1, false, mvpMtrx, 0)
|
||||||
|
|
||||||
|
GLES20.glDrawArrays(GLES20.GL_TRIANGLE_FAN, 0, mVrtxCount)
|
||||||
|
GLES20.glDisableVertexAttribArray(mPstnHandle)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun loopColor()
|
||||||
|
{
|
||||||
|
for (i in mGlobalColor.indices)
|
||||||
|
{
|
||||||
|
if (mColorUp[i]) {
|
||||||
|
if (mGlobalColor[i] <= 1.1)
|
||||||
|
mGlobalColor[i] += mColorIncrement[i]
|
||||||
|
else
|
||||||
|
mColorUp[i] = false
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (mGlobalColor[i] >= 0.01)
|
||||||
|
mGlobalColor[i] = mGlobalColor[i] - mColorIncrement[i]
|
||||||
|
else
|
||||||
|
mColorUp[i] = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,168 @@
|
|||||||
|
package pavelsobolev.kotogl.Spiral2D
|
||||||
|
|
||||||
|
import android.opengl.GLES20
|
||||||
|
import java.nio.ByteBuffer
|
||||||
|
import java.nio.ByteOrder
|
||||||
|
import java.nio.FloatBuffer
|
||||||
|
|
||||||
|
// represent the triangle which has different color for aech vertex with using of interpolation
|
||||||
|
// color of each vertex is changing cyclically during the process of rendering
|
||||||
|
class Triangle
|
||||||
|
{
|
||||||
|
|
||||||
|
private val COORDS_PER_VERTEX = 7
|
||||||
|
private val mFloatSizeInBytes = 4
|
||||||
|
|
||||||
|
private var mVertexBuffer: FloatBuffer? = null
|
||||||
|
|
||||||
|
private var mTriangle1VertData = floatArrayOf(
|
||||||
|
// X, Y, Z,
|
||||||
|
// R, G, B, A
|
||||||
|
-0.5f, -0.25f, 0.0f, // 0 1 2
|
||||||
|
1.0f, 0.0f, 0.0f, 1.0f, // 3 4 5 6
|
||||||
|
|
||||||
|
0.5f, -0.25f, 0.0f, // 7 8 9
|
||||||
|
0.0f, 1.0f, 0.0f, 1.0f, // 10 11 12 13
|
||||||
|
|
||||||
|
0.0f, 0.559016994f, 0.0f, // 14 15 16
|
||||||
|
0.0f, 0.0f, 1.0f, 1.0f // 17 18 19 20
|
||||||
|
)
|
||||||
|
|
||||||
|
private val mColors = floatArrayOf(
|
||||||
|
1.0f, 0.0f, 0.0f, 1.0f,
|
||||||
|
0.0f, 1.0f, 0.0f, 1.0f,
|
||||||
|
0.0f, 0.0f, 1.0f, 1.0f)
|
||||||
|
|
||||||
|
private val mColorIncrement = floatArrayOf(
|
||||||
|
0.05f, 0.001f, 0.025f, 0.001f,
|
||||||
|
0.02f, 0.02f, 0.025f, 0.001f,
|
||||||
|
0.01f, 0.005f, 0.025f, 0.001f,
|
||||||
|
0.04f, 0.005f, 0.025f, 0.001f)
|
||||||
|
|
||||||
|
private val mColorUp = booleanArrayOf(
|
||||||
|
false, true, true,
|
||||||
|
true, true, false,
|
||||||
|
true, true, true,
|
||||||
|
true, false, true)
|
||||||
|
|
||||||
|
private val mColorOffset = 3
|
||||||
|
|
||||||
|
//
|
||||||
|
private val mPositionDataSize = 3
|
||||||
|
|
||||||
|
/** Size of the color data in elements. */
|
||||||
|
private val mColorDataSize = 4
|
||||||
|
//internal var color = floatArrayOf(1.0f, 1.0f, 0.0f, 1.0f)
|
||||||
|
|
||||||
|
private val mVrtxShaderCode = "uniform mat4 uMVPMatrix;" +
|
||||||
|
"attribute vec4 a_Position;" +
|
||||||
|
"attribute vec4 a_Color;" +
|
||||||
|
"varying vec4 v_Color;" +
|
||||||
|
"void main() {" +
|
||||||
|
" v_Color = a_Color;" +
|
||||||
|
" gl_Position = uMVPMatrix * a_Position;" +
|
||||||
|
"}"
|
||||||
|
private val mFrgmntShaderCode = "precision mediump float;" +
|
||||||
|
"varying vec4 v_Color;" +
|
||||||
|
"void main() {" +
|
||||||
|
" gl_FragColor = v_Color;" +
|
||||||
|
"}"
|
||||||
|
|
||||||
|
private val mShaderProgram: Int
|
||||||
|
|
||||||
|
private var mPositionHandle: Int = 0
|
||||||
|
private var mColorHandle: Int = 0
|
||||||
|
private var mMVPMatrixHandle: Int = 0
|
||||||
|
|
||||||
|
private val vertexCount = mTriangle1VertData.size / COORDS_PER_VERTEX
|
||||||
|
private val vertexStride = COORDS_PER_VERTEX * 4 // 4 bytes per vertex
|
||||||
|
|
||||||
|
init // constructor
|
||||||
|
{
|
||||||
|
val vertexShader = MyGLRenderer.loadShader(GLES20.GL_VERTEX_SHADER,
|
||||||
|
mVrtxShaderCode)
|
||||||
|
val fragmentShader = MyGLRenderer.loadShader(GLES20.GL_FRAGMENT_SHADER,
|
||||||
|
mFrgmntShaderCode)
|
||||||
|
|
||||||
|
mShaderProgram = GLES20.glCreateProgram()
|
||||||
|
GLES20.glAttachShader(mShaderProgram, vertexShader)
|
||||||
|
GLES20.glAttachShader(mShaderProgram, fragmentShader)
|
||||||
|
GLES20.glBindAttribLocation(mShaderProgram, 0, "a_Position")
|
||||||
|
GLES20.glBindAttribLocation(mShaderProgram, 1, "a_Color")
|
||||||
|
GLES20.glLinkProgram(mShaderProgram)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun draw(mvpMatrix: FloatArray, x: Float, y: Float, z: Float)
|
||||||
|
{
|
||||||
|
|
||||||
|
mTriangle1VertData = floatArrayOf(
|
||||||
|
x, y + 0.08f, z,
|
||||||
|
mColors[0], mColors[1], mColors[2], mColors[3],
|
||||||
|
x - 0.08f, y - 0.08f, z,
|
||||||
|
mColors[4], mColors[5], mColors[6], mColors[7],
|
||||||
|
x + 0.08f, y - 0.08f, z,
|
||||||
|
mColors[8], mColors[9], mColors[10], mColors[11])
|
||||||
|
|
||||||
|
val bb = ByteBuffer.allocateDirect(mTriangle1VertData.size * mFloatSizeInBytes)
|
||||||
|
bb.order(ByteOrder.nativeOrder())
|
||||||
|
mVertexBuffer = bb.asFloatBuffer()
|
||||||
|
mVertexBuffer!!.put(mTriangle1VertData)
|
||||||
|
mVertexBuffer!!.position(0)
|
||||||
|
|
||||||
|
GLES20.glUseProgram(mShaderProgram)
|
||||||
|
|
||||||
|
loopColor() //change color cyclically
|
||||||
|
|
||||||
|
|
||||||
|
mPositionHandle = GLES20.glGetAttribLocation(mShaderProgram, "a_Position")
|
||||||
|
|
||||||
|
// triangle coordinate data
|
||||||
|
mVertexBuffer!!.position(0)
|
||||||
|
GLES20.glVertexAttribPointer(mPositionHandle, mPositionDataSize,
|
||||||
|
GLES20.GL_FLOAT, false,
|
||||||
|
vertexStride, mVertexBuffer)
|
||||||
|
|
||||||
|
GLES20.glEnableVertexAttribArray(mPositionHandle)
|
||||||
|
|
||||||
|
|
||||||
|
// Set mColors for drawing the triangle
|
||||||
|
|
||||||
|
mColorHandle = GLES20.glGetAttribLocation(mShaderProgram, "a_Color")
|
||||||
|
mVertexBuffer!!.position(mColorOffset)
|
||||||
|
GLES20.glVertexAttribPointer(mColorHandle, mColorDataSize, GLES20.GL_FLOAT, false,
|
||||||
|
vertexStride, mVertexBuffer)
|
||||||
|
GLES20.glEnableVertexAttribArray(mColorHandle)
|
||||||
|
|
||||||
|
mMVPMatrixHandle = GLES20.glGetUniformLocation(mShaderProgram, "uMVPMatrix")
|
||||||
|
GLES20.glUniformMatrix4fv(mMVPMatrixHandle, 1, false, mvpMatrix, 0)
|
||||||
|
|
||||||
|
// Draw the triangle
|
||||||
|
GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, vertexCount)
|
||||||
|
|
||||||
|
|
||||||
|
// Disable vertex array
|
||||||
|
GLES20.glDisableVertexAttribArray(mPositionHandle)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
fun loopColor() //change color of each vertex cyclically
|
||||||
|
{
|
||||||
|
for (k in 0..11)
|
||||||
|
{
|
||||||
|
if (mColorUp[k])
|
||||||
|
{
|
||||||
|
if (mColors[k] <= 1.1)
|
||||||
|
mColors[k] += mColorIncrement[k]
|
||||||
|
else
|
||||||
|
mColorUp[k] = false
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (mColors[k] >= 0.01)
|
||||||
|
mColors[k] -= mColorIncrement[k]
|
||||||
|
else
|
||||||
|
mColorUp[k] = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,31 @@
|
|||||||
|
package sgd.and04.layout
|
||||||
|
|
||||||
|
import android.content.Intent
|
||||||
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
|
import android.os.Bundle
|
||||||
|
import android.util.Log
|
||||||
|
import android.view.View
|
||||||
|
import android.widget.TextView
|
||||||
|
|
||||||
|
class TableActivity : AppCompatActivity() {
|
||||||
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
|
super.onCreate(savedInstanceState)
|
||||||
|
setContentView(R.layout.activity_table)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun onButtonLinearLayoutClick(view: View) {
|
||||||
|
startActivity(Intent(this, MainActivity::class.java))
|
||||||
|
}
|
||||||
|
|
||||||
|
fun onButtonRelativeLayoutClick(view: View) {
|
||||||
|
startActivity(Intent(this, RelativeActivity::class.java))
|
||||||
|
}
|
||||||
|
|
||||||
|
fun onButtonFrameLayoutClick(view: View) {
|
||||||
|
startActivity(Intent(this, FrameActivity::class.java))
|
||||||
|
}
|
||||||
|
|
||||||
|
fun onButtonGridLayoutClick(view: View) {
|
||||||
|
startActivity(Intent(this, GridActivity::class.java))
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,30 @@
|
|||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:aapt="http://schemas.android.com/aapt"
|
||||||
|
android:width="108dp"
|
||||||
|
android:height="108dp"
|
||||||
|
android:viewportWidth="108"
|
||||||
|
android:viewportHeight="108">
|
||||||
|
<path android:pathData="M31,63.928c0,0 6.4,-11 12.1,-13.1c7.2,-2.6 26,-1.4 26,-1.4l38.1,38.1L107,108.928l-32,-1L31,63.928z">
|
||||||
|
<aapt:attr name="android:fillColor">
|
||||||
|
<gradient
|
||||||
|
android:endX="85.84757"
|
||||||
|
android:endY="92.4963"
|
||||||
|
android:startX="42.9492"
|
||||||
|
android:startY="49.59793"
|
||||||
|
android:type="linear">
|
||||||
|
<item
|
||||||
|
android:color="#44000000"
|
||||||
|
android:offset="0.0" />
|
||||||
|
<item
|
||||||
|
android:color="#00000000"
|
||||||
|
android:offset="1.0" />
|
||||||
|
</gradient>
|
||||||
|
</aapt:attr>
|
||||||
|
</path>
|
||||||
|
<path
|
||||||
|
android:fillColor="#FFFFFF"
|
||||||
|
android:fillType="nonZero"
|
||||||
|
android:pathData="M65.3,45.828l3.8,-6.6c0.2,-0.4 0.1,-0.9 -0.3,-1.1c-0.4,-0.2 -0.9,-0.1 -1.1,0.3l-3.9,6.7c-6.3,-2.8 -13.4,-2.8 -19.7,0l-3.9,-6.7c-0.2,-0.4 -0.7,-0.5 -1.1,-0.3C38.8,38.328 38.7,38.828 38.9,39.228l3.8,6.6C36.2,49.428 31.7,56.028 31,63.928h46C76.3,56.028 71.8,49.428 65.3,45.828zM43.4,57.328c-0.8,0 -1.5,-0.5 -1.8,-1.2c-0.3,-0.7 -0.1,-1.5 0.4,-2.1c0.5,-0.5 1.4,-0.7 2.1,-0.4c0.7,0.3 1.2,1 1.2,1.8C45.3,56.528 44.5,57.328 43.4,57.328L43.4,57.328zM64.6,57.328c-0.8,0 -1.5,-0.5 -1.8,-1.2s-0.1,-1.5 0.4,-2.1c0.5,-0.5 1.4,-0.7 2.1,-0.4c0.7,0.3 1.2,1 1.2,1.8C66.5,56.528 65.6,57.328 64.6,57.328L64.6,57.328z"
|
||||||
|
android:strokeWidth="1"
|
||||||
|
android:strokeColor="#00000000" />
|
||||||
|
</vector>
|
After Width: | Height: | Size: 1.8 KiB |
After Width: | Height: | Size: 133 KiB |
After Width: | Height: | Size: 128 KiB |
@ -0,0 +1,7 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<comment version="3.0">
|
||||||
|
<caption/>
|
||||||
|
<note>acket = 0,12,-8 FaceNum=0 FocusArea=111111111</note>
|
||||||
|
<place/>
|
||||||
|
<categories/>
|
||||||
|
</comment>
|
@ -0,0 +1,7 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<comment version="3.0">
|
||||||
|
<caption/>
|
||||||
|
<note>acket = 0,12,-8 FaceNum=0 FocusArea=111111111</note>
|
||||||
|
<place/>
|
||||||
|
<categories/>
|
||||||
|
</comment>
|
@ -0,0 +1,7 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<comment version="3.0">
|
||||||
|
<caption/>
|
||||||
|
<note>Liquid marble texture design, colorful marbling surface, golden lines, vibrant abstract paint design, vector</note>
|
||||||
|
<place/>
|
||||||
|
<categories/>
|
||||||
|
</comment>
|
@ -0,0 +1,48 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<comment version="3.0">
|
||||||
|
<caption/>
|
||||||
|
<note>High quality marble texture.Seamless pattern.</note>
|
||||||
|
<place/>
|
||||||
|
<categories>
|
||||||
|
<category value="abstract"/>
|
||||||
|
<category value="backdrop"/>
|
||||||
|
<category value="background"/>
|
||||||
|
<category value="color"/>
|
||||||
|
<category value="colour"/>
|
||||||
|
<category value="cracked"/>
|
||||||
|
<category value="creative"/>
|
||||||
|
<category value="decoration"/>
|
||||||
|
<category value="decorative"/>
|
||||||
|
<category value="design"/>
|
||||||
|
<category value="effect"/>
|
||||||
|
<category value="geology"/>
|
||||||
|
<category value="graphic"/>
|
||||||
|
<category value="grunge"/>
|
||||||
|
<category value="hard"/>
|
||||||
|
<category value="illustration"/>
|
||||||
|
<category value="image"/>
|
||||||
|
<category value="marble"/>
|
||||||
|
<category value="marbled"/>
|
||||||
|
<category value="material"/>
|
||||||
|
<category value="mineral"/>
|
||||||
|
<category value="mountain"/>
|
||||||
|
<category value="natural"/>
|
||||||
|
<category value="nature"/>
|
||||||
|
<category value="old"/>
|
||||||
|
<category value="pattern"/>
|
||||||
|
<category value="purple"/>
|
||||||
|
<category value="repeat"/>
|
||||||
|
<category value="repetition"/>
|
||||||
|
<category value="rock"/>
|
||||||
|
<category value="rough"/>
|
||||||
|
<category value="seamless"/>
|
||||||
|
<category value="slate"/>
|
||||||
|
<category value="stone"/>
|
||||||
|
<category value="structure"/>
|
||||||
|
<category value="surface"/>
|
||||||
|
<category value="texture"/>
|
||||||
|
<category value="textured"/>
|
||||||
|
<category value="wallpaper"/>
|
||||||
|
<category value="weathered"/>
|
||||||
|
</categories>
|
||||||
|
</comment>
|
@ -0,0 +1,57 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<comment version="3.0">
|
||||||
|
<caption>Gold and cream color patterned natural of dark blue gray marble pattern background, abstract marble texture.</caption>
|
||||||
|
<note>Gold and cream color patterned natural of dark blue gray marble pattern background, abstract marble texture.</note>
|
||||||
|
<place/>
|
||||||
|
<categories>
|
||||||
|
<category value="floor"/>
|
||||||
|
<category value="darkness"/>
|
||||||
|
<category value="flooring"/>
|
||||||
|
<category value="dark"/>
|
||||||
|
<category value="background"/>
|
||||||
|
<category value="surface"/>
|
||||||
|
<category value="made"/>
|
||||||
|
<category value="wallpaper"/>
|
||||||
|
<category value="stone"/>
|
||||||
|
<category value="soft"/>
|
||||||
|
<category value="tile"/>
|
||||||
|
<category value="natural"/>
|
||||||
|
<category value="kitchen"/>
|
||||||
|
<category value="white"/>
|
||||||
|
<category value="bathroom"/>
|
||||||
|
<category value="rock"/>
|
||||||
|
<category value="marble"/>
|
||||||
|
<category value="deluxe"/>
|
||||||
|
<category value="luxury"/>
|
||||||
|
<category value="durable"/>
|
||||||
|
<category value="light"/>
|
||||||
|
<category value="decor"/>
|
||||||
|
<category value="black"/>
|
||||||
|
<category value="gray"/>
|
||||||
|
<category value="smooth"/>
|
||||||
|
<category value="abstract"/>
|
||||||
|
<category value="flat"/>
|
||||||
|
<category value="intrinsic"/>
|
||||||
|
<category value="marbled"/>
|
||||||
|
<category value="wall"/>
|
||||||
|
<category value="decorative"/>
|
||||||
|
<category value="complex"/>
|
||||||
|
<category value="backdrop"/>
|
||||||
|
<category value="texture"/>
|
||||||
|
<category value="boulder"/>
|
||||||
|
<category value="design"/>
|
||||||
|
<category value="architecture"/>
|
||||||
|
<category value="interior"/>
|
||||||
|
<category value="patterned"/>
|
||||||
|
<category value="gold"/>
|
||||||
|
<category value="original"/>
|
||||||
|
<category value="elegance"/>
|
||||||
|
<category value="nature"/>
|
||||||
|
<category value="detail"/>
|
||||||
|
<category value="pattern"/>
|
||||||
|
<category value="textured"/>
|
||||||
|
<category value="exterior"/>
|
||||||
|
<category value="raw"/>
|
||||||
|
<category value="material"/>
|
||||||
|
</categories>
|
||||||
|
</comment>
|
After Width: | Height: | Size: 1.5 KiB |
@ -0,0 +1,12 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:shape="rectangle">
|
||||||
|
<stroke
|
||||||
|
android:width="10dp"
|
||||||
|
android:color="#000000"/>
|
||||||
|
<corners android:radius="8dp" />
|
||||||
|
<gradient
|
||||||
|
android:startColor="#b2ce49"
|
||||||
|
android:endColor="#186dff"
|
||||||
|
android:angle="90"/>
|
||||||
|
</shape>
|
@ -0,0 +1,11 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<shape xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<solid android:color="#0000ff"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content" />
|
||||||
|
<corners android:radius="1dp"/>
|
||||||
|
<stroke android:width="2dp"
|
||||||
|
android:color="#000000"/>
|
||||||
|
<size android:width="64dp"
|
||||||
|
android:height="85dp"/>
|
||||||
|
</shape>
|
After Width: | Height: | Size: 1.1 KiB |
After Width: | Height: | Size: 5.6 MiB |
After Width: | Height: | Size: 2.9 MiB |
After Width: | Height: | Size: 2.6 MiB |
After Width: | Height: | Size: 3.1 MiB |
@ -0,0 +1,11 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<shape xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<solid android:color="#00ff00"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content" />
|
||||||
|
<corners android:radius="1dp"/>
|
||||||
|
<stroke android:width="2dp"
|
||||||
|
android:color="#000000"/>
|
||||||
|
<size android:width="64dp"
|
||||||
|
android:height="85dp"/>
|
||||||
|
</shape>
|
After Width: | Height: | Size: 302 KiB |
@ -0,0 +1,74 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<vector
|
||||||
|
android:height="108dp"
|
||||||
|
android:width="108dp"
|
||||||
|
android:viewportHeight="108"
|
||||||
|
android:viewportWidth="108"
|
||||||
|
xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<path android:fillColor="#26A69A"
|
||||||
|
android:pathData="M0,0h108v108h-108z"/>
|
||||||
|
<path android:fillColor="#00000000" android:pathData="M9,0L9,108"
|
||||||
|
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||||
|
<path android:fillColor="#00000000" android:pathData="M19,0L19,108"
|
||||||
|
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||||
|
<path android:fillColor="#00000000" android:pathData="M29,0L29,108"
|
||||||
|
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||||
|
<path android:fillColor="#00000000" android:pathData="M39,0L39,108"
|
||||||
|
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||||
|
<path android:fillColor="#00000000" android:pathData="M49,0L49,108"
|
||||||
|
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||||
|
<path android:fillColor="#00000000" android:pathData="M59,0L59,108"
|
||||||
|
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||||
|
<path android:fillColor="#00000000" android:pathData="M69,0L69,108"
|
||||||
|
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||||
|
<path android:fillColor="#00000000" android:pathData="M79,0L79,108"
|
||||||
|
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||||
|
<path android:fillColor="#00000000" android:pathData="M89,0L89,108"
|
||||||
|
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||||
|
<path android:fillColor="#00000000" android:pathData="M99,0L99,108"
|
||||||
|
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||||
|
<path android:fillColor="#00000000" android:pathData="M0,9L108,9"
|
||||||
|
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||||
|
<path android:fillColor="#00000000" android:pathData="M0,19L108,19"
|
||||||
|
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||||
|
<path android:fillColor="#00000000" android:pathData="M0,29L108,29"
|
||||||
|
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||||
|
<path android:fillColor="#00000000" android:pathData="M0,39L108,39"
|
||||||
|
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||||
|
<path android:fillColor="#00000000" android:pathData="M0,49L108,49"
|
||||||
|
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||||
|
<path android:fillColor="#00000000" android:pathData="M0,59L108,59"
|
||||||
|
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||||
|
<path android:fillColor="#00000000" android:pathData="M0,69L108,69"
|
||||||
|
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||||
|
<path android:fillColor="#00000000" android:pathData="M0,79L108,79"
|
||||||
|
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||||
|
<path android:fillColor="#00000000" android:pathData="M0,89L108,89"
|
||||||
|
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||||
|
<path android:fillColor="#00000000" android:pathData="M0,99L108,99"
|
||||||
|
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||||
|
<path android:fillColor="#00000000" android:pathData="M19,29L89,29"
|
||||||
|
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||||
|
<path android:fillColor="#00000000" android:pathData="M19,39L89,39"
|
||||||
|
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||||
|
<path android:fillColor="#00000000" android:pathData="M19,49L89,49"
|
||||||
|
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||||
|
<path android:fillColor="#00000000" android:pathData="M19,59L89,59"
|
||||||
|
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||||
|
<path android:fillColor="#00000000" android:pathData="M19,69L89,69"
|
||||||
|
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||||
|
<path android:fillColor="#00000000" android:pathData="M19,79L89,79"
|
||||||
|
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||||
|
<path android:fillColor="#00000000" android:pathData="M29,19L29,89"
|
||||||
|
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||||
|
<path android:fillColor="#00000000" android:pathData="M39,19L39,89"
|
||||||
|
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||||
|
<path android:fillColor="#00000000" android:pathData="M49,19L49,89"
|
||||||
|
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||||
|
<path android:fillColor="#00000000" android:pathData="M59,19L59,89"
|
||||||
|
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||||
|
<path android:fillColor="#00000000" android:pathData="M69,19L69,89"
|
||||||
|
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||||
|
<path android:fillColor="#00000000" android:pathData="M79,19L79,89"
|
||||||
|
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||||
|
</vector>
|
@ -0,0 +1,34 @@
|
|||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:aapt="http://schemas.android.com/aapt"
|
||||||
|
android:width="108dp"
|
||||||
|
android:height="108dp"
|
||||||
|
android:viewportHeight="108"
|
||||||
|
android:viewportWidth="108">
|
||||||
|
<path
|
||||||
|
android:fillType="evenOdd"
|
||||||
|
android:pathData="M32,64C32,64 38.39,52.99 44.13,50.95C51.37,48.37 70.14,49.57 70.14,49.57L108.26,87.69L108,109.01L75.97,107.97L32,64Z"
|
||||||
|
android:strokeColor="#00000000"
|
||||||
|
android:strokeWidth="1">
|
||||||
|
<aapt:attr name="android:fillColor">
|
||||||
|
<gradient
|
||||||
|
android:endX="78.5885"
|
||||||
|
android:endY="90.9159"
|
||||||
|
android:startX="48.7653"
|
||||||
|
android:startY="61.0927"
|
||||||
|
android:type="linear">
|
||||||
|
<item
|
||||||
|
android:color="#44000000"
|
||||||
|
android:offset="0.0" />
|
||||||
|
<item
|
||||||
|
android:color="#00000000"
|
||||||
|
android:offset="1.0" />
|
||||||
|
</gradient>
|
||||||
|
</aapt:attr>
|
||||||
|
</path>
|
||||||
|
<path
|
||||||
|
android:fillColor="#FFFFFF"
|
||||||
|
android:fillType="nonZero"
|
||||||
|
android:pathData="M66.94,46.02L66.94,46.02C72.44,50.07 76,56.61 76,64L32,64C32,56.61 35.56,50.11 40.98,46.06L36.18,41.19C35.45,40.45 35.45,39.3 36.18,38.56C36.91,37.81 38.05,37.81 38.78,38.56L44.25,44.05C47.18,42.57 50.48,41.71 54,41.71C57.48,41.71 60.78,42.57 63.68,44.05L69.11,38.56C69.84,37.81 70.98,37.81 71.71,38.56C72.44,39.3 72.44,40.45 71.71,41.19L66.94,46.02ZM62.94,56.92C64.08,56.92 65,56.01 65,54.88C65,53.76 64.08,52.85 62.94,52.85C61.8,52.85 60.88,53.76 60.88,54.88C60.88,56.01 61.8,56.92 62.94,56.92ZM45.06,56.92C46.2,56.92 47.13,56.01 47.13,54.88C47.13,53.76 46.2,52.85 45.06,52.85C43.92,52.85 43,53.76 43,54.88C43,56.01 43.92,56.92 45.06,56.92Z"
|
||||||
|
android:strokeColor="#00000000"
|
||||||
|
android:strokeWidth="1" />
|
||||||
|
</vector>
|
After Width: | Height: | Size: 789 B |
After Width: | Height: | Size: 705 B |
After Width: | Height: | Size: 196 B |
After Width: | Height: | Size: 641 B |
After Width: | Height: | Size: 518 B |
After Width: | Height: | Size: 742 B |
After Width: | Height: | Size: 206 KiB |
After Width: | Height: | Size: 130 KiB |
After Width: | Height: | Size: 582 KiB |
After Width: | Height: | Size: 148 KiB |
After Width: | Height: | Size: 450 KiB |
After Width: | Height: | Size: 90 KiB |
After Width: | Height: | Size: 1.1 MiB |
After Width: | Height: | Size: 28 KiB |
After Width: | Height: | Size: 155 KiB |
After Width: | Height: | Size: 1.2 MiB |
After Width: | Height: | Size: 348 KiB |
After Width: | Height: | Size: 172 KiB |
After Width: | Height: | Size: 344 KiB |
After Width: | Height: | Size: 1009 KiB |
After Width: | Height: | Size: 1.0 KiB |
@ -0,0 +1,11 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<shape xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<solid android:color="#ff0000"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content" />
|
||||||
|
<corners android:radius="1dp"/>
|
||||||
|
<stroke android:width="2dp"
|
||||||
|
android:color="#000000"/>
|
||||||
|
<size android:width="64dp"
|
||||||
|
android:height="85dp"/>
|
||||||
|
</shape>
|
After Width: | Height: | Size: 2.3 KiB |
After Width: | Height: | Size: 1.7 KiB |
@ -0,0 +1,12 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:shape="oval">
|
||||||
|
<solid android:color="#ff0000"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content" />
|
||||||
|
<corners android:radius="1dp"/>
|
||||||
|
<stroke android:width="2dp"
|
||||||
|
android:color="#FFF"/>
|
||||||
|
<size android:width="64dp"
|
||||||
|
android:height="64dp"/>
|
||||||
|
</shape>
|
After Width: | Height: | Size: 3.4 KiB |
After Width: | Height: | Size: 767 B |
@ -0,0 +1,141 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
tools:context="DistanceActivity">
|
||||||
|
|
||||||
|
<ScrollView
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent">
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="vertical">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/textView"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginBottom="10dp"
|
||||||
|
android:layout_marginTop="10dp"
|
||||||
|
android:paddingBottom="5dp"
|
||||||
|
android:paddingTop="5dp"
|
||||||
|
android:text="@string/pos_header"
|
||||||
|
android:textAlignment="center"
|
||||||
|
android:textSize="25sp"
|
||||||
|
android:textStyle="bold" />
|
||||||
|
|
||||||
|
<View
|
||||||
|
android:id="@+id/divider2"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="1dp"
|
||||||
|
android:background="?android:attr/listDivider" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/textViewCenter"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="5dp"
|
||||||
|
android:text="@string/center_pos_txt"
|
||||||
|
android:textAlignment="center"
|
||||||
|
android:textSize="18sp" />
|
||||||
|
|
||||||
|
<SeekBar
|
||||||
|
android:id="@+id/seekBarCentral"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginEnd="5dp"
|
||||||
|
android:max="7" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/textViewLeft"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="5dp"
|
||||||
|
android:text="@string/left_pos_txt"
|
||||||
|
android:textAlignment="center"
|
||||||
|
android:textSize="18sp" />
|
||||||
|
|
||||||
|
<SeekBar
|
||||||
|
android:id="@+id/seekBarLeft"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginEnd="5dp"
|
||||||
|
android:max="7" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/textViewRight"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="5dp"
|
||||||
|
android:text="@string/right_pos_txt"
|
||||||
|
android:textAlignment="center"
|
||||||
|
android:textSize="18sp" />
|
||||||
|
|
||||||
|
<SeekBar
|
||||||
|
android:id="@+id/seekBarRight"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginEnd="5dp"
|
||||||
|
android:max="7" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/textViewTop"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="5dp"
|
||||||
|
android:text="@string/top_pos_txt"
|
||||||
|
android:textAlignment="center"
|
||||||
|
android:textSize="18sp" />
|
||||||
|
|
||||||
|
<SeekBar
|
||||||
|
android:id="@+id/seekBarTop"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginEnd="5dp"
|
||||||
|
android:max="7" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/textViewBottom"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="5dp"
|
||||||
|
android:text="@string/bottom_pos_txt"
|
||||||
|
android:textAlignment="center"
|
||||||
|
android:textSize="18sp" />
|
||||||
|
|
||||||
|
<SeekBar
|
||||||
|
android:id="@+id/seekBarBottom"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginEnd="5dp"
|
||||||
|
android:max="7" />
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:orientation="horizontal">
|
||||||
|
|
||||||
|
<Button
|
||||||
|
android:id="@+id/buttonOk"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:text="@string/btn_ok" />
|
||||||
|
|
||||||
|
<Button
|
||||||
|
android:id="@+id/buttonCancel"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:text="@string/btn_cancel" />
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
</ScrollView>
|
||||||
|
|
||||||
|
|
||||||
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
@ -0,0 +1,57 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:background="@drawable/app_background"
|
||||||
|
android:onClick="onLayoutClick">
|
||||||
|
<ImageView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
app:srcCompat="@drawable/red_card"
|
||||||
|
android:layout_marginStart="30dp"
|
||||||
|
android:layout_marginTop="30dp"/>
|
||||||
|
<ImageView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
app:srcCompat="@drawable/green_card"
|
||||||
|
android:layout_marginStart="50dp"
|
||||||
|
android:layout_marginTop="50dp"/>
|
||||||
|
<ImageView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
app:srcCompat="@drawable/blue_card"
|
||||||
|
android:layout_marginStart="70dp"
|
||||||
|
android:layout_marginTop="70dp"/>
|
||||||
|
<ImageView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
app:srcCompat="@drawable/red_card"
|
||||||
|
android:layout_gravity="end"
|
||||||
|
android:layout_marginEnd="30dp"
|
||||||
|
android:layout_marginTop="30dp"/>
|
||||||
|
<ImageView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
app:srcCompat="@drawable/green_card"
|
||||||
|
android:layout_gravity="end"
|
||||||
|
android:layout_marginEnd="50dp"
|
||||||
|
android:layout_marginTop="50dp"/>
|
||||||
|
<ImageView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
app:srcCompat="@drawable/blue_card"
|
||||||
|
android:layout_gravity="end"
|
||||||
|
android:layout_marginEnd="70dp"
|
||||||
|
android:layout_marginTop="70dp"/>
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="@string/layout_uebersicht"
|
||||||
|
android:layout_marginLeft="30dp"
|
||||||
|
android:layout_marginBottom="15dp"
|
||||||
|
android:padding="10dp"
|
||||||
|
android:background="#aa000000"
|
||||||
|
android:textColor="#ffffff"
|
||||||
|
android:layout_gravity="bottom|left"/>
|
||||||
|
</FrameLayout>
|
@ -0,0 +1,32 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<GridLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:padding="16dp"
|
||||||
|
android:orientation="vertical">
|
||||||
|
<ImageView
|
||||||
|
android:layout_gravity="top|center"
|
||||||
|
app:srcCompat="@drawable/headline_icon"/>
|
||||||
|
<TextView
|
||||||
|
android:text="@string/layout_uebersicht"/>
|
||||||
|
<Button
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:onClick="onButtonLinearLayoutClick"
|
||||||
|
android:text="@string/linear_layout"/>
|
||||||
|
<Button
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:onClick="onButtonTableLayoutClick"
|
||||||
|
android:text="@string/table_layout"/>
|
||||||
|
<Button
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:onClick="onButtonRelativeLayoutClick"
|
||||||
|
android:text="@string/relative_layout"/>
|
||||||
|
<Button
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:onClick="onButtonFrameLayoutClick"
|
||||||
|
android:text="@string/frame_layout"/>
|
||||||
|
<ImageView
|
||||||
|
android:layout_gravity="bottom|center"
|
||||||
|
app:srcCompat="@drawable/baseline_icon"/>
|
||||||
|
</GridLayout>
|
@ -0,0 +1,44 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:id="@+id/frame_layout">
|
||||||
|
<Button
|
||||||
|
android:backgroundTint="#fa0"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginStart="5dp"
|
||||||
|
android:id="@+id/prev"
|
||||||
|
android:text="Prev"/>
|
||||||
|
|
||||||
|
<Button
|
||||||
|
android:backgroundTint="#fa0"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_gravity="end"
|
||||||
|
android:layout_marginEnd="5dp"
|
||||||
|
android:id="@+id/next"
|
||||||
|
android:text="Next"/>
|
||||||
|
<ScrollView
|
||||||
|
android:layout_width="fill_parent"
|
||||||
|
android:layout_height="fill_parent">
|
||||||
|
|
||||||
|
|
||||||
|
<HorizontalScrollView
|
||||||
|
android:layout_width="fill_parent"
|
||||||
|
android:layout_height="fill_parent"
|
||||||
|
android:id="@+id/scrollView">
|
||||||
|
|
||||||
|
</HorizontalScrollView>
|
||||||
|
</ScrollView>
|
||||||
|
<Button
|
||||||
|
android:backgroundTint="#fa0"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_gravity="end|bottom"
|
||||||
|
android:layout_marginEnd="5dp"
|
||||||
|
android:onClick="onButtonExitClick"
|
||||||
|
|
||||||
|
android:text="Exit"/>
|
||||||
|
</FrameLayout>
|
@ -0,0 +1,73 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
android:layout_width="fill_parent"
|
||||||
|
android:layout_height="fill_parent"
|
||||||
|
android:background="@drawable/app_background"
|
||||||
|
tools:context=".MainActivity">
|
||||||
|
|
||||||
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:gravity="center"
|
||||||
|
|
||||||
|
android:padding="16dp"
|
||||||
|
|
||||||
|
|
||||||
|
tools:context=".MainActivity">
|
||||||
|
<ImageView
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
app:srcCompat="@drawable/headline_icon"/>
|
||||||
|
<TextView
|
||||||
|
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="@string/layout_uebersicht"/>
|
||||||
|
<Button
|
||||||
|
android:backgroundTint="#fa0"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:onClick="onButtonTableLayoutClick"
|
||||||
|
android:text="@string/table_layout"/>
|
||||||
|
<Button
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:onClick="onButtonRelativeLayoutClick"
|
||||||
|
android:text="@string/relative_layout"/>
|
||||||
|
|
||||||
|
<Button
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:onClick="onButtonFrameLayoutClick"
|
||||||
|
android:text="@string/frame_layout"/>
|
||||||
|
|
||||||
|
<Button
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:onClick="onButtonGridLayoutClick"
|
||||||
|
android:text="@string/grid_layout"/>
|
||||||
|
|
||||||
|
<Button
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:onClick="onButtonScrollLayoutClick"
|
||||||
|
android:text="ScrollLayout"/>
|
||||||
|
|
||||||
|
<Button
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:onClick="onButtonImageSwitcherClick"
|
||||||
|
android:text="ImageSwitcher"/>
|
||||||
|
|
||||||
|
<Button
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:onClick="onButtonOpenGLClick"
|
||||||
|
android:text="OpenGL"/>
|
||||||
|
</LinearLayout>
|
||||||
|
</ScrollView>
|
@ -0,0 +1,34 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
tools:context="MainScreenActivity">
|
||||||
|
|
||||||
|
<com.google.android.material.appbar.AppBarLayout
|
||||||
|
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:theme="@style/AppBarOverlay">
|
||||||
|
|
||||||
|
<androidx.appcompat.widget.Toolbar
|
||||||
|
android:id="@+id/toolbar"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="?attr/actionBarSize"
|
||||||
|
android:background="@color/purple_500"
|
||||||
|
app:popupTheme="@style/AppPopupOverlay" />
|
||||||
|
|
||||||
|
</com.google.android.material.appbar.AppBarLayout>
|
||||||
|
|
||||||
|
<include layout="@layout/content_main_screen" />
|
||||||
|
|
||||||
|
<com.google.android.material.floatingactionbutton.FloatingActionButton
|
||||||
|
android:id="@+id/fab"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_gravity="bottom|end"
|
||||||
|
android:layout_margin="@dimen/fab_margin"
|
||||||
|
app:srcCompat="@android:drawable/ic_btn_speak_now" />
|
||||||
|
|
||||||
|
</androidx.coordinatorlayout.widget.CoordinatorLayout>
|
@ -0,0 +1,19 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
tools:context=".OpenGLActivity">
|
||||||
|
<android.opengl.GLSurfaceView
|
||||||
|
|
||||||
|
android:layout_width="300dp"
|
||||||
|
|
||||||
|
android:layout_height="300dp"
|
||||||
|
|
||||||
|
android:id="@+id/my_surface_view"
|
||||||
|
|
||||||
|
/>
|
||||||
|
|
||||||
|
|
||||||
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
@ -0,0 +1,83 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:padding="16dp"
|
||||||
|
android:background="@drawable/app_background">
|
||||||
|
<ImageView
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
app:srcCompat="@drawable/headline_icon"
|
||||||
|
android:layout_alignParentTop="true"/>
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_centerInParent="true"
|
||||||
|
android:layout_centerHorizontal="true"
|
||||||
|
android:orientation="vertical">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="Layoutübersicht:"
|
||||||
|
android:id="@+id/textview_relative"/>
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:id="@+id/linearLayout"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_below="@+id/textview_relative"
|
||||||
|
android:orientation="vertical">
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content">
|
||||||
|
|
||||||
|
<Button
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginHorizontal="10dp"
|
||||||
|
android:onClick="onButtonLinearLayoutClick"
|
||||||
|
android:text="@string/linear_layout"/>
|
||||||
|
|
||||||
|
<Button
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginHorizontal="20dp"
|
||||||
|
android:onClick="onButtonTableLayoutClick"
|
||||||
|
android:text="@string/table_layout"/>
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="horizontal"
|
||||||
|
android:gravity="center">
|
||||||
|
|
||||||
|
<Button
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginHorizontal="10dp"
|
||||||
|
android:onClick="onButtonFrameLayoutClick"
|
||||||
|
android:text="@string/frame_layout"/>
|
||||||
|
|
||||||
|
<Button
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginHorizontal="30dp"
|
||||||
|
android:onClick="onButtonGridLayoutClick"
|
||||||
|
android:text="@string/grid_layout" />
|
||||||
|
</LinearLayout>
|
||||||
|
</LinearLayout>
|
||||||
|
</LinearLayout>
|
||||||
|
<ImageView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
app:srcCompat="@drawable/baseline_icon"
|
||||||
|
android:layout_alignParentBottom="true"
|
||||||
|
android:layout_centerHorizontal="true"/>
|
||||||
|
|
||||||
|
</RelativeLayout>
|
@ -0,0 +1,32 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
|
||||||
|
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:background="@drawable/app_background">
|
||||||
|
|
||||||
|
<ScrollView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:id="@+id/scrollView">
|
||||||
|
|
||||||
|
<HorizontalScrollView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content">
|
||||||
|
<ImageView
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
app:srcCompat="@drawable/horseshoe"/>
|
||||||
|
</HorizontalScrollView>
|
||||||
|
</ScrollView>
|
||||||
|
|
||||||
|
<Button
|
||||||
|
android:backgroundTint="#fa0"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginStart="5dp"
|
||||||
|
android:onClick="onButtonExitClick"
|
||||||
|
android:text="Exit"/>
|
||||||
|
|
||||||
|
</FrameLayout>
|
@ -0,0 +1,35 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<TableLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
android:layout_width="fill_parent"
|
||||||
|
android:layout_height="fill_parent"
|
||||||
|
android:background="@drawable/app_background"
|
||||||
|
android:gravity="center"
|
||||||
|
android:id="@+id/tableLayout"
|
||||||
|
>
|
||||||
|
<TableRow>
|
||||||
|
<TextView android:text="@string/layout_uebersicht"
|
||||||
|
android:layout_span="4"
|
||||||
|
android:padding="20dp"/>
|
||||||
|
</TableRow>
|
||||||
|
<TableRow
|
||||||
|
android:padding="8dp">
|
||||||
|
<ImageView app:srcCompat="@drawable/android"/>
|
||||||
|
<Button android:text="@string/linear_layout"
|
||||||
|
android:onClick="onButtonLinearLayoutClick"/>
|
||||||
|
<ImageView app:srcCompat="@drawable/android" />
|
||||||
|
<Button android:text="@string/relative_layout"
|
||||||
|
android:onClick="onButtonRelativeLayoutClick"/>
|
||||||
|
</TableRow>
|
||||||
|
<TableRow
|
||||||
|
android:layout_width="fill_parent"
|
||||||
|
android:gravity="center_vertical"
|
||||||
|
android:padding="8dp">
|
||||||
|
<ImageView app:srcCompat="@drawable/android"/>
|
||||||
|
<Button android:text="@string/frame_layout"
|
||||||
|
android:onClick="onButtonFrameLayoutClick"/>
|
||||||
|
<ImageView app:srcCompat="@drawable/android" />
|
||||||
|
<Button android:text="@string/grid_layout"
|
||||||
|
android:onClick="onButtonGridLayoutClick"/>
|
||||||
|
</TableRow>
|
||||||
|
</TableLayout>
|
@ -0,0 +1,14 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
android:id="@+id/mainLayout"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:background="@drawable/app_background"
|
||||||
|
|
||||||
|
app:layout_behavior="@string/appbar_scrolling_view_behavior"
|
||||||
|
tools:context="MainScreenActivity"
|
||||||
|
tools:showIn="@layout/activity_main_screen">
|
||||||
|
|
||||||
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
@ -0,0 +1,24 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:background="@drawable/app_background"
|
||||||
|
android:onClick="onLayoutClick">
|
||||||
|
<ImageView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
app:srcCompat="@drawable/stop"
|
||||||
|
android:layout_marginStart="30dp"
|
||||||
|
android:layout_marginTop="30dp"/>
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="STOP"
|
||||||
|
android:layout_marginLeft="35dp"
|
||||||
|
android:layout_marginTop="40dp"
|
||||||
|
android:padding="10dp"
|
||||||
|
android:textColor="#ffffff"
|
||||||
|
android:layout_gravity="top|left"/>
|
||||||
|
</FrameLayout>
|
@ -0,0 +1,68 @@
|
|||||||
|
<menu xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
tools:context="pavelsobolev.kotogl.Activities.MainScreenActivity">
|
||||||
|
<!--item
|
||||||
|
android:id="@+id/action_2DCurve"
|
||||||
|
android:orderInCategory="100"
|
||||||
|
android:icon="@drawable/curve"
|
||||||
|
android:title="@string/action_settings2DP"
|
||||||
|
app:showAsAction="always" /-->
|
||||||
|
<!--item
|
||||||
|
android:id="@+id/action_2DCurve"
|
||||||
|
android:orderInCategory="100"
|
||||||
|
android:icon="@drawable/curve"
|
||||||
|
android:title="@string/action_settings2DP"
|
||||||
|
app:showAsAction="always" /-->
|
||||||
|
<item
|
||||||
|
android:id="@+id/action_2D"
|
||||||
|
android:orderInCategory="100"
|
||||||
|
android:icon="@drawable/spiral"
|
||||||
|
android:title="@string/action_settings2D"
|
||||||
|
app:showAsAction="always" />
|
||||||
|
<item
|
||||||
|
android:id="@+id/action_3D"
|
||||||
|
android:orderInCategory="101"
|
||||||
|
android:title="@string/action_settings3D"
|
||||||
|
android:icon="@drawable/if_ic_3d_rotation_48px_351995"
|
||||||
|
app:showAsAction="always" />
|
||||||
|
<item
|
||||||
|
android:id="@+id/action_Rotate"
|
||||||
|
android:checkable="true"
|
||||||
|
android:checked="true"
|
||||||
|
android:icon="@drawable/leftright"
|
||||||
|
android:orderInCategory="102"
|
||||||
|
android:title="@string/action_settingRotatDirection"
|
||||||
|
app:showAsAction="always" />
|
||||||
|
<item
|
||||||
|
android:id="@+id/action_Tilt"
|
||||||
|
android:orderInCategory="103"
|
||||||
|
android:title="@string/action_tilt"
|
||||||
|
android:icon="@drawable/rotate"
|
||||||
|
app:showAsAction="always"
|
||||||
|
android:visible="false"/>
|
||||||
|
<item
|
||||||
|
android:id="@+id/action_manual"
|
||||||
|
android:orderInCategory="104"
|
||||||
|
android:title="@string/action_settingsManual"
|
||||||
|
android:icon="@drawable/if_ic_history_48px_352426"
|
||||||
|
app:showAsAction="always" />
|
||||||
|
<item
|
||||||
|
android:id="@+id/action_settingsDistance"
|
||||||
|
android:orderInCategory="105"
|
||||||
|
android:icon="@drawable/if_ic_dashboard_48px_352300"
|
||||||
|
android:title="@string/action_settingPos"
|
||||||
|
app:showAsAction="never" />
|
||||||
|
<item
|
||||||
|
android:id="@+id/action_swap_textures"
|
||||||
|
android:orderInCategory="106"
|
||||||
|
android:icon="@drawable/if_3d_touch_2_1504646"
|
||||||
|
android:title="@string/action_swp"
|
||||||
|
app:showAsAction="never" />
|
||||||
|
<item
|
||||||
|
android:id="@+id/action_exit"
|
||||||
|
android:orderInCategory="106"
|
||||||
|
android:icon="@drawable/if_3d_touch_2_1504646"
|
||||||
|
android:title="Exit"
|
||||||
|
app:showAsAction="never" />
|
||||||
|
</menu>
|
@ -0,0 +1,5 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<background android:drawable="@drawable/ic_launcher_background" />
|
||||||
|
<foreground android:drawable="@drawable/ic_launcher_foreground" />
|
||||||
|
</adaptive-icon>
|
@ -0,0 +1,5 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<background android:drawable="@drawable/ic_launcher_background" />
|
||||||
|
<foreground android:drawable="@drawable/ic_launcher_foreground" />
|
||||||
|
</adaptive-icon>
|
After Width: | Height: | Size: 1.4 KiB |
After Width: | Height: | Size: 2.8 KiB |
After Width: | Height: | Size: 982 B |
After Width: | Height: | Size: 1.7 KiB |