Merge pull request #1761 from Sonicadvance1/Android_stereoscopy

Adds stereoscopy configuration support to Android.
This commit is contained in:
Ryan Houdek 2014-12-28 15:15:27 -06:00
commit 83d9942ca3
8 changed files with 226 additions and 1 deletions

View File

@ -0,0 +1,22 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:weightSum="1"
android:gravity="center_horizontal">
<SeekBar
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/seekBar"
/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="New Text"
android:id="@+id/textView"
android:textStyle="bold"/>
</LinearLayout>

View File

@ -155,5 +155,18 @@
<item>3</item>
<item>4</item>
</string-array>
<!-- Stereoscopy Preference -->
<string-array name="stereoscopyEntries" translatable="false">
<item>Off</item>
<item>Side-by-Side</item>
<item>Top-and-Bottom</item>
<item>Anaglyph</item>
</string-array>
<string-array name="stereoscopyValues" translatable="false">
<item>0</item>
<item>1</item>
<item>2</item>
<item>3</item>
</string-array>
</resources>

View File

@ -174,6 +174,16 @@
<string name="force_texture_filtering_descrip">Force texture filtering even if the emulated game explicitly disabled it. Improves texture quality slightly but causes glitches in some games.</string>
<string name="disable_fog">Disable Fog</string>
<string name="disable_fog_descrip">Makes distant objects more visible by removing fog, thus increasing the overall detail. Disabling fog will break some games which rely on proper fog emulation.</string>
<string name="stereoscopy">Stereoscopy</string>
<string name="stereoscopy_descrip">Stereoscopy allows you to get a better feeling of depth if you have the necessary hardware.\nHeavily decreases emulation speed and sometimes causes issues</string>
<string name="stereoscopy_mode">Stereoscopy Mode</string>
<string name="stereoscopy_mode_descrip">Select the stereoscopic 3D mode.</string>
<string name="sterescopy_depth">Depthn</string>
<string name="sterescopy_depth_descrip">Control the distance between the virtual cameras.\nA higher value creates a stronger feeling of depth while a lower value is more comfortable.</string>
<string name="convergence">Convergence</string>
<string name="convergence_descrip">Control the distance of the convergence plane, this is the distance at which objects will appear to be in front of the screen.\nA higher value creates stronger out-of-screen effects while a lower value is more comfortable.</string>
<string name="swap_eyes">Swap Eyes</string>
<string name="swap_eyes_descrip">Swap the left and right eye, mostly useful if you want to view side-by-side cross-eyed.</string>
<string name="hacks">Hacks</string>
<string name="embedded_frame_buffer">Embedded Frame Buffer</string>

View File

@ -57,6 +57,38 @@
android:summary="@string/disable_fog_descrip"
android:title="@string/disable_fog"/>
<PreferenceScreen
android:title="@string/stereoscopy"
android:key="StereoscopyScreen"
android:summary="@string/stereoscopy_descrip">
<ListPreference
android:entries="@array/stereoscopyEntries"
android:entryValues="@array/stereoscopyValues"
android:key="stereoscopyMode"
android:summary="@string/stereoscopy_mode_descrip"
android:title="@string/stereoscopy_mode"/>
<org.dolphinemu.dolphinemu.utils.SliderPreference
android:defaultValue="20"
android:key="stereoDepth"
android:max="100"
android:summary="@string/sterescopy_depth_descrip"
android:title="@string/sterescopy_depth" />
<org.dolphinemu.dolphinemu.utils.SliderPreference
android:defaultValue="20"
android:key="stereoConvergence"
android:max="500"
android:summary="@string/convergence_descrip"
android:title="@string/convergence" />
<CheckBoxPreference
android:defaultValue="false"
android:key="stereoSwapEyes"
android:summary="@string/swap_eyes_descrip"
android:title="@string/swap_eyes"/>
</PreferenceScreen>
</PreferenceScreen>
<!-- Video Hacks -->

View File

@ -57,6 +57,10 @@ public final class UserPreferences
editor.putBoolean("disableFog", getConfig("gfx_opengl.ini", "Settings", "DisableFog", "False").equals("True"));
editor.putBoolean("skipEFBAccess", getConfig("gfx_opengl.ini", "Hacks", "EFBAccessEnable", "False").equals("True"));
editor.putBoolean("ignoreFormatChanges", getConfig("gfx_opengl.ini", "Hacks", "EFBEmulateFormatChanges", "False").equals("False"));
editor.putString("stereoscopyMode", getConfig("gfx_opengl.ini", "Enhancements", "StereoMode", "0"));
editor.putBoolean("stereoSwapEyes", getConfig("gfx_opengl.ini", "Enhancements", "StereoSwapEyes", "False").equals("True"));
editor.putString("stereoDepth", getConfig("gfx_opengl.ini", "Enhancements", "StereoDepth", "20"));
editor.putString("stereoConvergence", getConfig("gfx_opengl.ini", "Enhancements", "StereoConvergence", "20"));
String efbCopyOn = getConfig("gfx_opengl.ini", "Hacks", "EFBCopyEnable", "True");
String efbToTexture = getConfig("gfx_opengl.ini", "Hacks", "EFBToTextureEnable", "True");
@ -182,6 +186,17 @@ public final class UserPreferences
// Whether or not fog is disabled.
boolean fogIsDisabled = prefs.getBoolean("disableFog", false);
// Stereoscopy setting
String stereoscopyMode = prefs.getString("stereoscopyMode", "0");
// Stereoscopy swap eyes
boolean stereoscopyEyeSwap = prefs.getBoolean("stereoSwapEyes", false);
// Stereoscopy separation
String stereoscopySeparation = prefs.getString("stereoDepth", "20");
// Stereoscopy convergence
String stereoscopyConvergence = prefs.getString("stereoConvergence", "20");
// CPU related Settings
NativeLibrary.SetConfig("Dolphin.ini", "Core", "CPUCore", currentEmuCore);
@ -251,5 +266,9 @@ public final class UserPreferences
NativeLibrary.SetConfig("gfx_opengl.ini", "Settings", "EnablePixelLighting", usingPerPixelLighting ? "True" : "False");
NativeLibrary.SetConfig("gfx_opengl.ini", "Enhancements", "ForceFiltering", isForcingTextureFiltering ? "True" : "False");
NativeLibrary.SetConfig("gfx_opengl.ini", "Settings", "DisableFog", fogIsDisabled ? "True" : "False");
NativeLibrary.SetConfig("gfx_opengl.ini", "Enhancements", "StereoMode", stereoscopyMode);
NativeLibrary.SetConfig("gfx_opengl.ini", "Enhancements", "StereoSwapEyes", stereoscopyEyeSwap ? "True" : "False");
NativeLibrary.SetConfig("gfx_opengl.ini", "Enhancements", "StereoDepth", stereoscopySeparation);
NativeLibrary.SetConfig("gfx_opengl.ini", "Enhancements", "StereoConvergence", stereoscopyConvergence);
}
}

View File

@ -121,6 +121,15 @@ public final class VideoSettingsFragment extends PreferenceFragment
mainScreen.getPreference(0).setEnabled(true);
mainScreen.getPreference(1).setEnabled(true);
mainScreen.getPreference(3).setEnabled(true);
// Check if we support stereo
// If we support desktop GL then we must support at least OpenGL 3.2
// If we only support OpenGLES then we need both OpenGLES 3.1 and AEP
if ((eglHelper.supportsOpenGL() && eglHelper.GetVersion() >= 320) ||
(eglHelper.supportsGLES3() && eglHelper.GetVersion() >= 310 && eglHelper.SupportsExtension("GL_ANDROID_extension_pack_es31a")))
mainScreen.findPreference("StereoscopyScreen").setEnabled(true);
else
mainScreen.findPreference("StereoscopyScreen").setEnabled(false);
}
// Also set a listener, so that if someone changes the video backend, it will disable

View File

@ -354,6 +354,29 @@ public final class EGLHelper
return GLES30.glGetStringi(glEnum, index);
}
public boolean SupportsExtension(String extension)
{
int[] num_ext = new int[1];
GLES30.glGetIntegerv(GLES30.GL_NUM_EXTENSIONS, num_ext, 0);
for (int i = 0; i < num_ext[0]; ++i)
{
String ext = GLES30.glGetStringi(GLES30.GL_EXTENSIONS, i);
if (ext.equals(extension))
return true;
}
return false;
}
public int GetVersion()
{
int[] major = new int[1];
int[] minor = new int[1];
GLES30.glGetIntegerv(GLES30.GL_MAJOR_VERSION, major, 0);
GLES30.glGetIntegerv(GLES30.GL_MINOR_VERSION, minor, 0);
return major[0] * 100 + minor[0] * 10;
}
/**
* Simplified call to {@link GL10#glGetIntegerv(int, int[], int)
*

View File

@ -0,0 +1,97 @@
package org.dolphinemu.dolphinemu.utils;
import android.app.AlertDialog;
import android.content.Context;
import android.os.Bundle;
import android.preference.DialogPreference;
import android.util.AttributeSet;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.SeekBar;
import android.widget.TextView;
import org.dolphinemu.dolphinemu.R;
public class SliderPreference extends DialogPreference implements SeekBar.OnSeekBarChangeListener, View.OnClickListener
{
private static final String androidns = "http://schemas.android.com/apk/res/android";
private Context m_context;
// SeekBar
private int m_max, m_value;
private SeekBar m_seekbar;
// TextView
private TextView m_textview;
public SliderPreference(Context context, AttributeSet attrs)
{
super(context,attrs);
m_context = context;
// Seekbar values
m_value = attrs.getAttributeIntValue(androidns, "defaultValue", 0);
m_max = attrs.getAttributeIntValue(androidns, "max", 100);
}
@Override
protected View onCreateDialogView()
{
LayoutInflater inflater = LayoutInflater.from(m_context);
LinearLayout layout = (LinearLayout)inflater.inflate(R.layout.slider_layout, null, false);
m_seekbar = (SeekBar)layout.getChildAt(0);
m_textview = (TextView)layout.getChildAt(1);
if (shouldPersist())
m_value = Integer.valueOf(getPersistedString(Integer.toString(m_value)));
m_seekbar.setMax(m_max);
m_seekbar.setProgress(m_value);
setProgressText(m_value);
m_seekbar.setOnSeekBarChangeListener(this);
return layout;
}
// SeekBar overrides
@Override
public void onProgressChanged(SeekBar seek, int value, boolean fromTouch)
{
m_value = value;
setProgressText(value);
}
@Override
public void onStartTrackingTouch(SeekBar seek) {}
@Override
public void onStopTrackingTouch(SeekBar seek) {}
void setProgressText(int value)
{
m_textview.setText(String.valueOf(value));
}
@Override
public void showDialog(Bundle state) {
super.showDialog(state);
Button positiveButton = ((AlertDialog) getDialog()).getButton(AlertDialog.BUTTON_POSITIVE);
positiveButton.setOnClickListener(this);
}
@Override
public void onClick(View v) {
if (shouldPersist())
{
persistString(Integer.toString(m_seekbar.getProgress()));
callChangeListener(m_seekbar.getProgress());
}
((AlertDialog) getDialog()).dismiss();
}
}