Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 7 additions & 2 deletions app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -153,11 +153,16 @@ abstract class CompileSlangShadersTask : DefaultTask() {

val compileProcess = ProcessBuilder(
"slangc", file.absolutePath, "-target", "spirv", "-o", outputFile.absolutePath
).inheritIO().start()
).redirectErrorStream(true).start()

val output = compileProcess.inputStream.bufferedReader().readText()
if (output.isNotBlank()) {
logger.lifecycle(output.trim())
}

val exitCode = compileProcess.waitFor()
if (exitCode != 0) {
throw GradleException("slangc failed compiling ${file.name} with exit code $exitCode")
throw GradleException("slangc failed compiling ${file.name} with exit code $exitCode, see log for details")
}
}
}
Expand Down
Binary file added app/src/generated/assets/shaders/egui.spv
Binary file not shown.
Binary file removed app/src/generated/assets/shaders/gltf.spv
Binary file not shown.
Binary file modified app/src/generated/assets/shaders/gltf_unlit_translucent.spv
Binary file not shown.
Binary file added app/src/main/assets/fonts/symbols.ttf
Binary file not shown.
Binary file added app/src/main/assets/meshes/keyboard.glb
Binary file not shown.
54 changes: 54 additions & 0 deletions app/src/main/assets/shaders/egui.slang
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
struct VertexInput {
float2 pos : POSITION;
float2 uv : TEXCOORD0;
uint color : COLOR;
}

struct VertexOutput {
float4 position : SV_Position;
float4 color : COLOR;
float2 uv : TEXCOORD0;
}

struct PushConstants {
float2 screen_size;
}

[[vk::binding(0, 0)]]
Sampler2D font_sampler_lle;

float4 linear_from_srgba(float4 srgba) {
bool4 cutoff = srgba < 0.04045;
float4 higher = pow((srgba + 0.055) / 1.055, 2.4);
float4 lower = srgba / 12.92;

return lerp(higher, lower, float4(cutoff));
}

float4 srgba_from_linear(float4 linear) {
bool4 cutoff = linear < 0.0031308;
float4 higher = 1.055 * pow(linear, 1.0 / 2.4) - 0.055;
float4 lower = linear * 12.92;

return lerp(higher, lower, float4(cutoff));
}

[shader("vertex")]
VertexOutput vertex_main(
uniform PushConstants pc,
VertexInput input
) {
VertexOutput output;
float2 pos = (input.pos / pc.screen_size) * 2.0 - 1.0;
output.position = float4(pos, 0.0, 1.0);

output.color = linear_from_srgba(unpackUnorm4x8ToFloat(input.color));
output.uv = input.uv;

return output;
}

[shader("fragment")]
float4 fragment_main(VertexOutput input) {
return srgba_from_linear(input.color * font_sampler_lle.Sample(input.uv));
}
1 change: 0 additions & 1 deletion app/src/main/assets/shaders/gltf_unlit_translucent.slang
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,6 @@ float4 fragment_main(VertexStageOutput input) : SV_Target {
tex_albedo = float4(0.0);
}

clip(tex_albedo.a - 0.1);
albedo *= tex_albedo;
}

Expand Down
13 changes: 12 additions & 1 deletion app/src/main/java/com/qcxr/questcraft/JniBridge.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,19 @@

import android.content.res.AssetManager;
import android.view.Surface;
import com.qcxr.questcraft.ui.XrTextInputBridge;

@SuppressWarnings("unused")
public class JniBridge {
static {
System.loadLibrary("qcxr");
}

public static native void setSkinImage(byte[] imageBytes, boolean slim);
public static native void start(MainActivity activity, AssetManager assetManager);
public static native void stop();
public static native void setSkinImage(byte[] imageBytes, boolean slim);
public static native void showKeyboard();
public static native void hideKeyboard();

public static void setVulkanSurface(Surface surface, int width, int height) {
MainActivity.instance().ifPresent(me -> me.setVulkanSurface(surface, width, height));
Expand All @@ -28,4 +31,12 @@ public static void requestUiRender() {
public static void processPointerEvent(int pointerId, int action, float normX, float normY) {
MainActivity.instance().ifPresent(me -> me.processPointerEvent(pointerId, action, normX, normY));
}

public static void sendText(String text) {
XrTextInputBridge.sendText(text);
}

public static void deleteCharacter() {
XrTextInputBridge.deleteCharacter();
}
}
13 changes: 0 additions & 13 deletions app/src/main/java/com/qcxr/questcraft/MainActivity.java
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
package com.qcxr.questcraft;

import android.annotation.SuppressLint;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.util.DisplayMetrics;
import android.view.Surface;
import android.view.View;
import android.view.ViewGroup;
Expand Down Expand Up @@ -38,7 +36,6 @@ public static Optional<MainActivity> instance() {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//setDensity();
weakMe = new WeakReference<>(this);
uiThreadHandler = new Handler(Looper.getMainLooper());
xrActivityInput = new XRActivityInput(uiThreadHandler);
Expand Down Expand Up @@ -76,16 +73,6 @@ private void deviceCodeCallback(DeviceCode res) {
}
}

private void setDensity() {
DisplayMetrics metrics = getResources().getDisplayMetrics();
float density = 0.75f;
float densityMultiplier = 160;
metrics.density = density;
metrics.ydpi = metrics.xdpi = densityMultiplier * density;
metrics.densityDpi = (int)metrics.xdpi;
getResources().updateConfiguration(null, null);
}

public void setVulkanSurface(Surface surface, int width, int height) {
runOnUiThread(() -> {
this.nativeSurface = new NativeSurface(this);
Expand Down
57 changes: 57 additions & 0 deletions app/src/main/java/com/qcxr/questcraft/ui/XrTextInputBridge.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
package com.qcxr.questcraft.ui

import android.os.Handler
import android.os.Looper
import androidx.compose.ui.text.TextRange
import androidx.compose.ui.text.input.TextFieldValue
import com.qcxr.questcraft.JniBridge

object XrTextInputBridge {
private val mainHandler = Handler(Looper.getMainLooper())

private data class ActiveField(
val getValue: () -> TextFieldValue,
val setValue: (TextFieldValue) -> Unit,
)

@Volatile private var active: ActiveField? = null

internal fun register(getValue: () -> TextFieldValue, setValue: (TextFieldValue) -> Unit) {
active = ActiveField(getValue, setValue)
JniBridge.showKeyboard()
}

internal fun unregister(getValue: () -> TextFieldValue) {
if (active?.getValue === getValue) {
active = null
JniBridge.hideKeyboard()
}
}

@JvmStatic
fun sendText(text: String) {
mainHandler.post {
val field = active ?: return@post
val v = field.getValue()
val newText = v.text.replaceRange(v.selection.start, v.selection.end, text)
val newCursor = v.selection.start + text.length
field.setValue(TextFieldValue(newText, TextRange(newCursor)))
}
}

@JvmStatic
fun deleteCharacter() {
mainHandler.post {
val field = active ?: return@post
val v = field.getValue()
if (v.selection.start != v.selection.end) {
val newText = v.text.removeRange(v.selection.start, v.selection.end)
field.setValue(TextFieldValue(newText, TextRange(v.selection.start)))
} else if (v.selection.start > 0) {
val cut = v.selection.start - 1
val newText = v.text.removeRange(cut, v.selection.start)
field.setValue(TextFieldValue(newText, TextRange(cut)))
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import androidx.compose.foundation.layout.*
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material3.Button
import androidx.compose.material3.ButtonDefaults
import androidx.compose.material3.OutlinedTextField
import androidx.compose.material3.OutlinedTextFieldDefaults
import androidx.compose.material3.Surface
import androidx.compose.material3.Text
Expand All @@ -17,6 +16,7 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.input.TextFieldValue
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
Expand All @@ -28,7 +28,7 @@ fun AddInstanceOverlay(
onDismiss: () -> Unit,
onCreate: (name: String, version: String, loader: String) -> Unit
) {
var instanceName by remember { mutableStateOf("") }
var instanceName by remember { mutableStateOf(TextFieldValue(text = "")) }
var selectedVersion by remember { mutableStateOf("1.20.1") }
var selectedLoader by remember { mutableStateOf("Fabric") }

Expand Down Expand Up @@ -62,7 +62,7 @@ fun AddInstanceOverlay(

Text(text = stringResource(R.string.instance_name), color = TextSecondary, fontSize = 12.sp)
Spacer(modifier = Modifier.height(8.dp))
OutlinedTextField(
XrOutlinedTextField(
value = instanceName,
onValueChange = { instanceName = it },
modifier = Modifier.fillMaxWidth(),
Expand Down Expand Up @@ -128,10 +128,10 @@ fun AddInstanceOverlay(
Spacer(modifier = Modifier.width(8.dp))

Button(
onClick = { onCreate(instanceName, selectedVersion, selectedLoader) },
onClick = { onCreate(instanceName.text, selectedVersion, selectedLoader) },
colors = ButtonDefaults.buttonColors(containerColor = AccentGreen),
shape = RoundedCornerShape(4.dp),
enabled = instanceName.isNotBlank()
enabled = instanceName.text.isNotBlank()
) {
Text(text = stringResource(R.string.create), color = Color.White)
}
Expand Down
87 changes: 87 additions & 0 deletions app/src/main/java/com/qcxr/questcraft/ui/components/XrTextField.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
package com.qcxr.questcraft.ui.components

import androidx.compose.foundation.interaction.MutableInteractionSource
import androidx.compose.foundation.text.KeyboardActions
import androidx.compose.foundation.text.KeyboardOptions
import androidx.compose.material3.LocalTextStyle
import androidx.compose.material3.OutlinedTextField
import androidx.compose.material3.OutlinedTextFieldDefaults
import androidx.compose.material3.TextFieldColors
import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberUpdatedState
import androidx.compose.ui.Modifier
import androidx.compose.ui.focus.onFocusChanged
import androidx.compose.ui.graphics.Shape
import androidx.compose.ui.platform.LocalSoftwareKeyboardController
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.input.TextFieldValue
import androidx.compose.ui.text.input.VisualTransformation
import com.qcxr.questcraft.ui.XrTextInputBridge

@Composable
fun XrOutlinedTextField(
value: TextFieldValue,
onValueChange: (TextFieldValue) -> Unit,
modifier: Modifier = Modifier,
enabled: Boolean = true,
readOnly: Boolean = false,
textStyle: TextStyle = LocalTextStyle.current,
label: @Composable (() -> Unit)? = null,
placeholder: @Composable (() -> Unit)? = null,
leadingIcon: @Composable (() -> Unit)? = null,
trailingIcon: @Composable (() -> Unit)? = null,
prefix: @Composable (() -> Unit)? = null,
suffix: @Composable (() -> Unit)? = null,
supportingText: @Composable (() -> Unit)? = null,
isError: Boolean = false,
visualTransformation: VisualTransformation = VisualTransformation.None,
keyboardOptions: KeyboardOptions = KeyboardOptions.Default,
keyboardActions: KeyboardActions = KeyboardActions.Default,
singleLine: Boolean = false,
maxLines: Int = if (singleLine) 1 else Int.MAX_VALUE,
minLines: Int = 1,
interactionSource: MutableInteractionSource? = null,
shape: Shape = OutlinedTextFieldDefaults.shape,
colors: TextFieldColors = OutlinedTextFieldDefaults.colors(),
) {
val keyboardController = LocalSoftwareKeyboardController.current
val currentValue = rememberUpdatedState(value)
val currentOnValueChange = rememberUpdatedState(onValueChange)

val getValue = remember { { currentValue.value } }
val setValue = remember { { v: TextFieldValue -> currentOnValueChange.value(v) } }

OutlinedTextField(
value = value,
onValueChange = onValueChange,
textStyle = textStyle,
modifier = modifier.onFocusChanged { focus ->
if (focus.isFocused) {
keyboardController?.hide()
XrTextInputBridge.register(getValue, setValue)
} else {
XrTextInputBridge.unregister(getValue)
}
},
enabled = enabled,
readOnly = readOnly,
label = label,
placeholder = placeholder,
leadingIcon = leadingIcon,
trailingIcon = trailingIcon,
prefix = prefix,
suffix = suffix,
supportingText = supportingText,
isError = isError,
visualTransformation = visualTransformation,
keyboardOptions = keyboardOptions,
keyboardActions = keyboardActions,
singleLine = singleLine,
maxLines = maxLines,
minLines = minLines,
interactionSource = interactionSource,
shape = shape,
colors = colors,
)
}
2 changes: 1 addition & 1 deletion app/src/main/rust/cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ bytemuck = { version = "1.25", features = ["derive"] }
glam = { version = "0.33", features = ["bytemuck", "mint"] }
mint = "0.5"
openxr = { git = "https://github.com/Ralith/openxrs.git", rev = "294809e4fe7f6f9729c80526f5320d7d70408984", default-features = false, features = ["mint"] }
vk-graph = { version = "0.14.5" }
vk-graph = { version = "0.14.7" }
egui = { version = "0.35.0", features = [ "bytemuck" ] }

gltf = { version = "1.4", features = [ "extras", "names" ] }
Expand Down
Loading