mirror of
https://github.com/DrBeef/DVR.git
synced 2024-11-25 21:41:00 +00:00
Download Freedom & WAD Chooser
This commit is contained in:
parent
2f50889ce5
commit
ca1d92e24c
5 changed files with 839 additions and 290 deletions
0
app/src/main/assets/extraparams.txt
Normal file
0
app/src/main/assets/extraparams.txt
Normal file
282
app/src/main/java/com/drbeef/dvr/DownloadTask.java
Normal file
282
app/src/main/java/com/drbeef/dvr/DownloadTask.java
Normal file
|
@ -0,0 +1,282 @@
|
|||
package com.drbeef.dvr;
|
||||
|
||||
import android.app.ProgressDialog;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.os.AsyncTask;
|
||||
import android.os.SystemClock;
|
||||
import android.util.Log;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.InputStream;
|
||||
import java.net.URL;
|
||||
import java.util.zip.ZipEntry;
|
||||
import java.util.zip.ZipFile;
|
||||
|
||||
import doom.util.DoomTools;
|
||||
|
||||
|
||||
class DownloadTask extends AsyncTask<Void, String, Void> {
|
||||
|
||||
private Context context;
|
||||
private ProgressDialog pd;
|
||||
|
||||
public boolean please_abort = false;
|
||||
|
||||
private String url = "https://www.dropbox.com/s/whngowjwpkwjht2/freedoom.zip?dl=1";
|
||||
private String freedoomZip = DoomTools.GetDVRFolder() + "/freedoom.zip";
|
||||
private String wadfile = DoomTools.GetDVRFolder() + "/freedoom.wad";
|
||||
|
||||
public DownloadTask set_context(Context context){
|
||||
this.context = context;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPreExecute (){
|
||||
|
||||
pd = new ProgressDialog(context);
|
||||
|
||||
pd.setTitle("Downloading FREEDOOM WAD file ...");
|
||||
pd.setMessage("starting");
|
||||
pd.setIndeterminate(true);
|
||||
pd.setCancelable(true);
|
||||
|
||||
pd.setOnDismissListener( new DialogInterface.OnDismissListener(){
|
||||
public void onDismiss(DialogInterface dialog) {
|
||||
Log.i( "DownloadTask.java", "onDismiss");
|
||||
please_abort = true;
|
||||
}
|
||||
});
|
||||
|
||||
pd.setOnCancelListener( new DialogInterface.OnCancelListener(){
|
||||
public void onCancel(DialogInterface dialog) {
|
||||
Log.i( "DownloadTask.java", "onCancel");
|
||||
please_abort = true;
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
pd.setButton(ProgressDialog.BUTTON_POSITIVE, "Cancel", new DialogInterface.OnClickListener() {
|
||||
public void onClick(DialogInterface dialog, int id) {
|
||||
pd.dismiss();
|
||||
please_abort = true;
|
||||
}
|
||||
});
|
||||
|
||||
pd.show();
|
||||
|
||||
}
|
||||
|
||||
|
||||
public static String printSize( int size ){
|
||||
|
||||
if ( size >= (1<<20) )
|
||||
return String.format("%.1f MB", size * (1.0/(1<<20)));
|
||||
|
||||
if ( size >= (1<<10) )
|
||||
return String.format("%.1f KB", size * (1.0/(1<<10)));
|
||||
|
||||
return String.format("%d bytes", size);
|
||||
|
||||
}
|
||||
|
||||
|
||||
private void download_demo() throws Exception{
|
||||
|
||||
Log.i( "DownloadTask.java", "starting to download "+ url);
|
||||
|
||||
if (new File(freedoomZip).exists()){
|
||||
Log.i( "DownloadTask.java", freedoomZip + " already there. skipping.");
|
||||
return;
|
||||
}
|
||||
|
||||
/// setup output directory
|
||||
new File(DoomTools.GetDVRFolder()).mkdirs();
|
||||
|
||||
InputStream is = null;
|
||||
FileOutputStream fos = null;
|
||||
|
||||
is = new URL(url).openStream();
|
||||
fos = new FileOutputStream ( freedoomZip +".part");
|
||||
|
||||
byte[] buffer = new byte [4096];
|
||||
|
||||
int totalcount =0;
|
||||
|
||||
long tprint = SystemClock.uptimeMillis();
|
||||
int partialcount = 0;
|
||||
|
||||
while(true){
|
||||
|
||||
if (please_abort)
|
||||
throw new Exception("aborting") ;
|
||||
|
||||
|
||||
int count = is.read (buffer);
|
||||
|
||||
if ( count<=0 ) break;
|
||||
fos.write (buffer, 0, count);
|
||||
|
||||
totalcount += count;
|
||||
partialcount += count;
|
||||
|
||||
long tnow = SystemClock.uptimeMillis();
|
||||
if ( (tnow-tprint)> 1000) {
|
||||
|
||||
float size_MB = totalcount * (1.0f/(1<<20));
|
||||
float speed_KB = partialcount * (1.0f/(1<<10)) * ((tnow-tprint)/1000.0f);
|
||||
|
||||
publishProgress( String.format("downloaded %.1f MB (%.1f KB/sec)",
|
||||
size_MB, speed_KB));
|
||||
|
||||
tprint = tnow;
|
||||
partialcount = 0;
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
is.close();
|
||||
fos.close();
|
||||
|
||||
|
||||
new File(freedoomZip +".part" )
|
||||
.renameTo(new File(freedoomZip));
|
||||
|
||||
// done
|
||||
publishProgress("download done" );
|
||||
|
||||
SystemClock.sleep(2000);
|
||||
|
||||
}
|
||||
|
||||
private void extract_data() throws Exception{
|
||||
Log.i("DownloadTask.java", "extracting WAD data");
|
||||
|
||||
ZipFile file = new ZipFile (freedoomZip);
|
||||
extract_file( file, "freedoom.wad", wadfile);
|
||||
|
||||
file.close();
|
||||
|
||||
// done
|
||||
publishProgress("extract done" );
|
||||
|
||||
pd.getButton(ProgressDialog.BUTTON_POSITIVE).setText("Done");
|
||||
|
||||
SystemClock.sleep(1000);
|
||||
|
||||
}
|
||||
|
||||
private void extract_file( ZipFile file, String entry_name, String output_name ) throws Exception{
|
||||
|
||||
Log.i( "DownloadTask.java", "extracting " + entry_name + " to " + output_name);
|
||||
|
||||
String short_name = new File(output_name).getName();
|
||||
|
||||
// create output directory
|
||||
new File(output_name).getParentFile().mkdirs();
|
||||
|
||||
ZipEntry entry = file.getEntry(entry_name);
|
||||
|
||||
if ( entry.isDirectory() ){
|
||||
Log.i( "DownloadTask.java", entry_name + " is a directory");
|
||||
new File(output_name).mkdir();
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
InputStream is = null;
|
||||
FileOutputStream fos = null;
|
||||
|
||||
is = file.getInputStream(entry);
|
||||
|
||||
fos = new FileOutputStream ( output_name+".part" );
|
||||
|
||||
byte[] buffer = new byte [4096];
|
||||
|
||||
int totalcount =0;
|
||||
|
||||
long tprint = SystemClock.uptimeMillis();
|
||||
|
||||
while(true){
|
||||
|
||||
if (please_abort)
|
||||
throw new Exception("aborting") ;
|
||||
|
||||
|
||||
int count = is.read (buffer);
|
||||
//Log.i( "DownloadTask.java", "extracted " + count + " bytes");
|
||||
|
||||
if ( count<=0 ) break;
|
||||
fos.write (buffer, 0, count);
|
||||
|
||||
totalcount += count;
|
||||
|
||||
long tnow = SystemClock.uptimeMillis();
|
||||
if ( (tnow-tprint)> 1000) {
|
||||
|
||||
float size_MB = totalcount * (1.0f/(1<<20));
|
||||
|
||||
publishProgress( String.format("%s : extracted %.1f MB",
|
||||
short_name, size_MB));
|
||||
|
||||
tprint = tnow;
|
||||
}
|
||||
}
|
||||
|
||||
is.close();
|
||||
fos.close();
|
||||
|
||||
/// rename part file
|
||||
|
||||
new File(output_name+".part" )
|
||||
.renameTo(new File(output_name));
|
||||
|
||||
// done
|
||||
publishProgress( String.format("%s : done.",
|
||||
short_name));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Void doInBackground(Void... unused) {
|
||||
|
||||
try {
|
||||
|
||||
//Inform game we are now downloading
|
||||
//QVRJNILib.setDownloadStatus(2);
|
||||
|
||||
long t = SystemClock.uptimeMillis();
|
||||
|
||||
download_demo();
|
||||
|
||||
extract_data();
|
||||
|
||||
t = SystemClock.uptimeMillis() - t;
|
||||
|
||||
Log.i( "DownloadTask.java", "done in " + t + " ms");
|
||||
|
||||
} catch (Exception e) {
|
||||
|
||||
e.printStackTrace();
|
||||
|
||||
//QVRJNILib.setDownloadStatus(0);
|
||||
publishProgress("Error: " + e );
|
||||
}
|
||||
|
||||
return(null);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onProgressUpdate(String... progress) {
|
||||
Log.i( "DownloadTask.java", progress[0]);
|
||||
pd.setMessage( progress[0]);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPostExecute(Void unused) {
|
||||
pd.hide();
|
||||
}
|
||||
}
|
|
@ -27,8 +27,11 @@ import com.google.vrtoolkit.cardboard.Eye;
|
|||
import com.google.vrtoolkit.cardboard.HeadTransform;
|
||||
import com.google.vrtoolkit.cardboard.Viewport;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.FileReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
|
@ -51,23 +54,14 @@ public class MainActivity
|
|||
{
|
||||
private static final String TAG = "DVR";
|
||||
|
||||
private static final int GL_RGBA8 = 0x8058;
|
||||
|
||||
private int[] currentFBO = new int[1];
|
||||
|
||||
//Head orientation
|
||||
private float[] eulerAngles = new float[3];
|
||||
|
||||
OpenGL openGL = null;
|
||||
|
||||
// Audio Cache Manager
|
||||
private AudioManager mAudioMgr;
|
||||
|
||||
private int MONO = 0;
|
||||
private int STEREO = 1;
|
||||
|
||||
private int mStereoMode = STEREO;
|
||||
private int eyeID = 0;
|
||||
|
||||
static private Bitmap mDoomBitmap;
|
||||
private Bitmap mDoomBitmap;
|
||||
|
||||
// width of mBitmap
|
||||
private int mDoomWidth;
|
||||
|
@ -87,127 +81,11 @@ public class MainActivity
|
|||
|
||||
private CardboardView cardboardView;
|
||||
|
||||
private FloatBuffer screenVertices;
|
||||
|
||||
private int positionParam;
|
||||
private int texCoordParam;
|
||||
private int samplerParam;
|
||||
private int modelViewProjectionParam;
|
||||
|
||||
private float[] modelScreen;
|
||||
private float[] camera;
|
||||
private float[] view;
|
||||
private float[] modelViewProjection;
|
||||
private float[] modelView;
|
||||
|
||||
private float screenDistance = 8f;
|
||||
private float screenScale = 4f;
|
||||
|
||||
public static final String vs_Image =
|
||||
"uniform mat4 u_MVPMatrix;" +
|
||||
"attribute vec4 a_Position;" +
|
||||
"attribute vec2 a_texCoord;" +
|
||||
"varying vec2 v_texCoord;" +
|
||||
"void main() {" +
|
||||
" gl_Position = u_MVPMatrix * a_Position;" +
|
||||
" v_texCoord = a_texCoord;" +
|
||||
"}";
|
||||
|
||||
|
||||
public static final String fs_Image =
|
||||
"precision mediump float;" +
|
||||
"varying vec2 v_texCoord;" +
|
||||
"uniform sampler2D s_texture;" +
|
||||
"void main() {" +
|
||||
" gl_FragColor = texture2D( s_texture, v_texCoord );" +
|
||||
"}";
|
||||
|
||||
public static int loadShader(int type, String shaderCode){
|
||||
int shader = GLES20.glCreateShader(type);
|
||||
GLES20.glShaderSource(shader, shaderCode);
|
||||
GLES20.glCompileShader(shader);
|
||||
return shader;
|
||||
}
|
||||
|
||||
//FBO render eye buffer
|
||||
private DVRFBO fbo;
|
||||
|
||||
|
||||
static boolean CreateFBO( DVRFBO fbo, int width, int height)
|
||||
{
|
||||
Log.d(TAG, "CreateFBO");
|
||||
// Create the color buffer texture.
|
||||
GLES20.glGenTextures(1, fbo.ColorTexture, 0);
|
||||
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, fbo.ColorTexture[0]);
|
||||
GLES20.glTexImage2D(GLES20.GL_TEXTURE_2D, 0, GL_RGBA8, width, height, 0, GLES20.GL_RGBA, GLES20.GL_UNSIGNED_BYTE, null);
|
||||
GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_S, GLES20.GL_CLAMP_TO_EDGE);
|
||||
GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_T, GLES20.GL_CLAMP_TO_EDGE);
|
||||
GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_LINEAR);
|
||||
GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_LINEAR);
|
||||
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, 0);
|
||||
|
||||
// Create depth buffer.
|
||||
GLES20.glGenRenderbuffers(1, fbo.DepthBuffer, 0);
|
||||
GLES20.glBindRenderbuffer(GLES20.GL_RENDERBUFFER, fbo.DepthBuffer[0]);
|
||||
GLES20.glRenderbufferStorage(GLES20.GL_RENDERBUFFER, GLES11Ext.GL_DEPTH_COMPONENT24_OES, width, height);
|
||||
GLES20.glBindRenderbuffer(GLES20.GL_RENDERBUFFER, 0);
|
||||
|
||||
// Create the frame buffer.
|
||||
GLES20.glGenFramebuffers(1, fbo.FrameBuffer, 0);
|
||||
GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, fbo.FrameBuffer[0]);
|
||||
GLES20.glFramebufferRenderbuffer(GLES20.GL_FRAMEBUFFER, GLES20.GL_DEPTH_ATTACHMENT, GLES20.GL_RENDERBUFFER, fbo.DepthBuffer[0]);
|
||||
GLES20.glFramebufferTexture2D(GLES20.GL_FRAMEBUFFER, GLES20.GL_COLOR_ATTACHMENT0, GLES20.GL_TEXTURE_2D, fbo.ColorTexture[0], 0);
|
||||
int renderFramebufferStatus = GLES20.glCheckFramebufferStatus(GLES20.GL_FRAMEBUFFER);
|
||||
GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, 0);
|
||||
if ( renderFramebufferStatus != GLES20.GL_FRAMEBUFFER_COMPLETE )
|
||||
{
|
||||
Log.d(TAG, "Incomplete frame buffer object!!");
|
||||
return false;
|
||||
}
|
||||
|
||||
fbo.width = width;
|
||||
fbo.height = height;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void DestroyFBO( DVRFBO fbo )
|
||||
{
|
||||
GLES20.glDeleteFramebuffers( 1, fbo.FrameBuffer, 0 );
|
||||
fbo.FrameBuffer[0] = 0;
|
||||
GLES20.glDeleteRenderbuffers( 1, fbo.DepthBuffer, 0 );
|
||||
fbo.DepthBuffer[0] = 0;
|
||||
GLES20.glDeleteTextures( 1, fbo.ColorTexture, 0 );
|
||||
fbo.ColorTexture[0] = 0;
|
||||
fbo.width = 0;
|
||||
fbo.height = 0;
|
||||
}
|
||||
|
||||
// Geometric variables
|
||||
public static float vertices[];
|
||||
public static final short[] indices = new short[] {0, 1, 2, 0, 2, 3};
|
||||
public static final float uvs[] = new float[] {
|
||||
0.0f, 1.0f,
|
||||
0.0f, 0.0f,
|
||||
1.0f, 0.0f,
|
||||
1.0f, 1.0f
|
||||
};
|
||||
|
||||
public static final float[] SCREEN_COORDS = new float[] {
|
||||
-1.3f, -1.0f, 1.0f,
|
||||
-1.3f, 1.0f, 1.0f,
|
||||
1.3f, 1.0f, 1.0f,
|
||||
1.3f, -1.0f, 1.0f
|
||||
};
|
||||
|
||||
public FloatBuffer vertexBuffer;
|
||||
public ShortBuffer listBuffer;
|
||||
public FloatBuffer uvBuffer;
|
||||
|
||||
//Shader Program
|
||||
public static int sp_Image;
|
||||
private DownloadTask mDownloadTask = null;
|
||||
private WADChooser mWADChooser = null;
|
||||
|
||||
public static boolean mDVRInitialised = false;
|
||||
|
||||
//Can't rebuild eye buffers until surface changed flag recorded
|
||||
public static boolean mSurfaceChanged = false;
|
||||
|
||||
|
@ -264,6 +142,13 @@ public class MainActivity
|
|||
}
|
||||
}
|
||||
|
||||
public void startDownload()
|
||||
{
|
||||
mDownloadTask = new DownloadTask();
|
||||
mDownloadTask.set_context(MainActivity.this);
|
||||
mDownloadTask.execute();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
|
@ -282,29 +167,65 @@ public class MainActivity
|
|||
cardboardView.setRenderer(this);
|
||||
setCardboardView(cardboardView);
|
||||
|
||||
modelScreen = new float[16];
|
||||
camera = new float[16];
|
||||
view = new float[16];
|
||||
modelViewProjection = new float[16];
|
||||
modelView = new float[16];
|
||||
openGL = new OpenGL();
|
||||
openGL.onCreate();
|
||||
|
||||
vibrator = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE);
|
||||
|
||||
//At the very least ensure we have a directory containing a config file
|
||||
copy_asset("DVR.cfg", DoomTools.GetDVRFolder() + "/");
|
||||
copy_asset("prboom.wad", DoomTools.GetDVRFolder() + "/");
|
||||
copy_asset("DVR.cfg", DoomTools.GetDVRFolder() + File.separator);
|
||||
copy_asset("prboom.wad", DoomTools.GetDVRFolder() + File.separator);
|
||||
copy_asset("extraparams.txt", DoomTools.GetDVRFolder() + File.separator);
|
||||
|
||||
if (!DoomTools.wadsExist()) {
|
||||
MessageBox("Read this carefully",
|
||||
"You must install a game file. Tap \"Install WADs\" for auto-install. "
|
||||
+ "Tap \"Help Me!\" for instructions on manual installation. "
|
||||
+ "A fast WIFI network and SDCARD are required."
|
||||
+ "If you experience game problems, try the Cleanup option.");
|
||||
//See if user is trying to use command line params
|
||||
BufferedReader br;
|
||||
try {
|
||||
br = new BufferedReader(new FileReader(DoomTools.GetDVRFolder() + "extraparams.txt"));
|
||||
String s;
|
||||
StringBuilder sb=new StringBuilder(0);
|
||||
while ((s=br.readLine())!=null)
|
||||
sb.append(s + " ");
|
||||
br.close();
|
||||
|
||||
commandLineParams = new String(sb.toString());
|
||||
} catch (FileNotFoundException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
} catch (IOException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
if (!DoomTools.wadsExist()) {
|
||||
AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(
|
||||
this);
|
||||
|
||||
//Create the FBOs
|
||||
fbo = new DVRFBO();
|
||||
// set title
|
||||
alertDialogBuilder.setTitle("No WAD files found");
|
||||
|
||||
// set dialog message
|
||||
alertDialogBuilder
|
||||
.setMessage("Would you like to download the free FREEDOOM WAD (8MB)?\n\nIf you own or purchase the full game of Doom/Doom2 (or any other wad)you can click \'Cancel\' and copy the WAD file to the folder:\n\n{phonememory}/DVR")
|
||||
.setCancelable(false)
|
||||
.setPositiveButton("Download", new DialogInterface.OnClickListener() {
|
||||
public void onClick(DialogInterface dialog, int id) {
|
||||
MainActivity.this.startDownload();
|
||||
}
|
||||
})
|
||||
.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
|
||||
public void onClick(DialogInterface dialog, int id) {
|
||||
dialog.cancel();
|
||||
}
|
||||
});
|
||||
|
||||
// create alert dialog
|
||||
AlertDialog alertDialog = alertDialogBuilder.create();
|
||||
|
||||
// show it
|
||||
alertDialog.show();
|
||||
}
|
||||
|
||||
mWADChooser = new WADChooser(openGL);
|
||||
|
||||
// Audio?
|
||||
mAudioMgr = AudioManager.getInstance(this);
|
||||
|
@ -325,64 +246,12 @@ public class MainActivity
|
|||
mSurfaceChanged = true;
|
||||
}
|
||||
|
||||
void CopyBitmapToTexture(Bitmap bmp, int textureUnit)
|
||||
{
|
||||
// Bind texture to texturename
|
||||
GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
|
||||
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, textureUnit);
|
||||
|
||||
// Set filtering
|
||||
GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_LINEAR);
|
||||
GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_LINEAR);
|
||||
|
||||
// Set wrapping mode
|
||||
GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_S, GLES20.GL_CLAMP_TO_EDGE);
|
||||
GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_T, GLES20.GL_CLAMP_TO_EDGE);
|
||||
|
||||
// Load the bitmap into the bound texture.
|
||||
GLUtils.texImage2D(GLES20.GL_TEXTURE_2D, 0, bmp, 0);
|
||||
|
||||
//unbind
|
||||
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSurfaceCreated(EGLConfig config) {
|
||||
Log.i(TAG, "onSurfaceCreated");
|
||||
|
||||
ByteBuffer bbVertices = ByteBuffer.allocateDirect(SCREEN_COORDS.length * 4);
|
||||
bbVertices.order(ByteOrder.nativeOrder());
|
||||
screenVertices = bbVertices.asFloatBuffer();
|
||||
screenVertices.put(SCREEN_COORDS);
|
||||
screenVertices.position(0);
|
||||
|
||||
// initialize byte buffer for the draw list
|
||||
ByteBuffer dlb = ByteBuffer.allocateDirect(indices.length * 2);
|
||||
dlb.order(ByteOrder.nativeOrder());
|
||||
listBuffer = dlb.asShortBuffer();
|
||||
listBuffer.put(indices);
|
||||
listBuffer.position(0);
|
||||
|
||||
// Create the shaders, images
|
||||
int vertexShader = loadShader(GLES20.GL_VERTEX_SHADER, vs_Image);
|
||||
int fragmentShader = loadShader(GLES20.GL_FRAGMENT_SHADER, fs_Image);
|
||||
|
||||
sp_Image = GLES20.glCreateProgram(); // create empty OpenGL ES Program
|
||||
GLES20.glAttachShader(sp_Image, vertexShader); // add the vertex shader to program
|
||||
GLES20.glAttachShader(sp_Image, fragmentShader); // add the fragment shader to program
|
||||
GLES20.glLinkProgram(sp_Image); // creates OpenGL ES program executable
|
||||
|
||||
positionParam = GLES20.glGetAttribLocation(sp_Image, "a_Position");
|
||||
texCoordParam = GLES20.glGetAttribLocation(sp_Image, "a_texCoord");
|
||||
modelViewProjectionParam = GLES20.glGetUniformLocation(sp_Image, "u_MVPMatrix");
|
||||
samplerParam = GLES20.glGetUniformLocation(sp_Image, "s_texture");
|
||||
|
||||
|
||||
GLES20.glEnableVertexAttribArray(positionParam);
|
||||
GLES20.glEnableVertexAttribArray(texCoordParam);
|
||||
|
||||
// Build the camera matrix
|
||||
Matrix.setLookAtM(camera, 0, 0.0f, 0.0f, 0.01f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f);
|
||||
openGL.onSurfaceCreated(config);
|
||||
|
||||
//Start intro music
|
||||
mPlayer = MediaPlayer.create(this, R.raw.m010912339);
|
||||
|
@ -405,22 +274,27 @@ public class MainActivity
|
|||
// Bind texture to texturename
|
||||
GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
|
||||
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, splashTexture[0]);
|
||||
CopyBitmapToTexture(bmp, splashTexture[0]);
|
||||
}
|
||||
|
||||
public void SwitchStereoMode(int stereo_mode)
|
||||
{
|
||||
mStereoMode = stereo_mode;
|
||||
openGL.CopyBitmapToTexture(bmp, splashTexture[0]);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNewFrame(HeadTransform headTransform) {
|
||||
|
||||
headTransform.getEulerAngles(eulerAngles, 0);
|
||||
float yaw = eulerAngles[1] / (M_PI / 180.0f);
|
||||
float pitch = -eulerAngles[0] / (M_PI / 180.0f);
|
||||
float roll = -eulerAngles[2] / (M_PI / 180.0f);
|
||||
|
||||
if (!mShowingSpashScreen && mWADChooser.choosingWAD())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (!mDVRInitialised) {
|
||||
if (!mSurfaceChanged)
|
||||
return;
|
||||
|
||||
SetupUVCoords();
|
||||
openGL.SetupUVCoords();
|
||||
|
||||
//Reset our orientation
|
||||
cardboardView.resetHeadTracker();
|
||||
|
@ -428,7 +302,7 @@ public class MainActivity
|
|||
if (!mShowingSpashScreen) {
|
||||
final String[] argv;
|
||||
String args = new String();
|
||||
args = "doom -iwad " + WADChooser.GetChosenWAD();
|
||||
args = "doom -iwad " + mWADChooser.GetChosenWAD() + " " + commandLineParams;
|
||||
argv = args.split(" ");
|
||||
String dvr= DoomTools.GetDVRFolder();
|
||||
Natives.DoomInit(argv, dvr);
|
||||
|
@ -437,11 +311,6 @@ public class MainActivity
|
|||
}
|
||||
|
||||
if (mDVRInitialised) {
|
||||
headTransform.getEulerAngles(eulerAngles, 0);
|
||||
|
||||
float yaw = eulerAngles[1] / (M_PI / 180.0f);
|
||||
float pitch = -eulerAngles[0] / (M_PI / 180.0f);
|
||||
float roll = -eulerAngles[2] / (M_PI / 180.0f);
|
||||
if (Natives.gameState() == 0)
|
||||
Natives.DoomStartFrame(pitch, yaw, roll);
|
||||
else
|
||||
|
@ -451,7 +320,11 @@ public class MainActivity
|
|||
|
||||
@Override
|
||||
public void onDrawEye(Eye eye) {
|
||||
if (mDVRInitialised || mShowingSpashScreen) {
|
||||
if (!mShowingSpashScreen && mWADChooser.choosingWAD())
|
||||
{
|
||||
mWADChooser.onDrawEye(eye);
|
||||
}
|
||||
else if (mDVRInitialised || mShowingSpashScreen) {
|
||||
|
||||
if (mShowingSpashScreen) {
|
||||
GLES20.glEnable(GLES20.GL_SCISSOR_TEST);
|
||||
|
@ -463,7 +336,7 @@ public class MainActivity
|
|||
Natives.DoomDrawEye(eye.getType() - 1);
|
||||
|
||||
//Now we'll have a populated bitmap, copy to the fbo colour buffer
|
||||
CopyBitmapToTexture(mDoomBitmap, fbo.ColorTexture[0]);
|
||||
openGL.CopyBitmapToTexture(mDoomBitmap, openGL.fbo.ColorTexture[0]);
|
||||
}
|
||||
|
||||
GLES20.glViewport(eye.getViewport().x,
|
||||
|
@ -480,27 +353,27 @@ public class MainActivity
|
|||
eye.getViewport().height);
|
||||
GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT);
|
||||
|
||||
GLES20.glUseProgram(sp_Image);
|
||||
GLES20.glUseProgram(openGL.sp_Image);
|
||||
|
||||
if (Natives.gameState() != 0) {
|
||||
if (Natives.gameState() != 0 || mShowingSpashScreen) {
|
||||
// Apply the eye transformation to the camera.
|
||||
Matrix.multiplyMM(view, 0, eye.getEyeView(), 0, camera, 0);
|
||||
Matrix.multiplyMM(openGL.view, 0, eye.getEyeView(), 0, openGL.camera, 0);
|
||||
|
||||
// Build the ModelView and ModelViewProjection matrices
|
||||
// for calculating screen position.
|
||||
float[] perspective = eye.getPerspective(0.1f, 100.0f);
|
||||
|
||||
float scale = screenScale;
|
||||
float scale = openGL.screenScale;
|
||||
if (mShowingSpashScreen)
|
||||
scale /= 2;
|
||||
|
||||
// Object first appears directly in front of user.
|
||||
Matrix.setIdentityM(modelScreen, 0);
|
||||
Matrix.translateM(modelScreen, 0, 0, 0, -screenDistance);
|
||||
Matrix.scaleM(modelScreen, 0, scale, scale, 1.0f);
|
||||
Matrix.multiplyMM(modelView, 0, view, 0, modelScreen, 0);
|
||||
Matrix.multiplyMM(modelViewProjection, 0, perspective, 0, modelView, 0);
|
||||
GLES20.glVertexAttribPointer(positionParam, 3, GLES20.GL_FLOAT, false, 0, screenVertices);
|
||||
Matrix.setIdentityM(openGL.modelScreen, 0);
|
||||
Matrix.translateM(openGL.modelScreen, 0, 0, 0, -openGL.screenDistance);
|
||||
Matrix.scaleM(openGL.modelScreen, 0, scale, scale, 1.0f);
|
||||
Matrix.multiplyMM(openGL.modelView, 0, openGL.view, 0, openGL.modelScreen, 0);
|
||||
Matrix.multiplyMM(openGL.modelViewProjection, 0, perspective, 0, openGL.modelView, 0);
|
||||
GLES20.glVertexAttribPointer(openGL.positionParam, 3, GLES20.GL_FLOAT, false, 0, openGL.screenVertices);
|
||||
|
||||
} else {
|
||||
|
||||
|
@ -512,35 +385,35 @@ public class MainActivity
|
|||
|
||||
int pitchOffset = (int)(-(eulerAngles[0]/M_PI)*(eye.getViewport().height));
|
||||
|
||||
SetupTriangle(x, y, w, h);
|
||||
openGL.SetupTriangle(x, y, w, h);
|
||||
|
||||
// Calculate the projection and view transformation
|
||||
Matrix.orthoM(view, 0, 0, eye.getViewport().width, 0, eye.getViewport().height, 0, 50);
|
||||
Matrix.orthoM(openGL.view, 0, 0, eye.getViewport().width, 0, eye.getViewport().height, 0, 50);
|
||||
//Translate so origin is centre of image
|
||||
if (eye.getType() == Eye.Type.LEFT)
|
||||
Matrix.translateM(view, 0, w / 2, eye.getViewport().height / 2, 0);
|
||||
Matrix.translateM(openGL.view, 0, w / 2, eye.getViewport().height / 2, 0);
|
||||
else
|
||||
Matrix.translateM(view, 0, eye.getViewport().width - w / 2, eye.getViewport().height / 2, 0);
|
||||
Matrix.translateM(openGL.view, 0, eye.getViewport().width - w / 2, eye.getViewport().height / 2, 0);
|
||||
//rotate for head roll
|
||||
Matrix.rotateM(view, 0, (int) (-(eulerAngles[2] / M_PI) * 180.f), 0, 0, 1);
|
||||
Matrix.rotateM(openGL.view, 0, (int) (-(eulerAngles[2] / M_PI) * 180.f), 0, 0, 1);
|
||||
//translate back to where it was before
|
||||
if (eye.getType() == Eye.Type.LEFT)
|
||||
Matrix.translateM(view, 0, -w / 2, -eye.getViewport().height / 2, 0);
|
||||
Matrix.translateM(openGL.view, 0, -w / 2, -eye.getViewport().height / 2, 0);
|
||||
else
|
||||
Matrix.translateM(view, 0, w / 2 - eye.getViewport().width, -eye.getViewport().height / 2, 0);
|
||||
Matrix.translateM(openGL.view, 0, w / 2 - eye.getViewport().width, -eye.getViewport().height / 2, 0);
|
||||
//Now apply head pitch transformation
|
||||
Matrix.translateM(view, 0, 0, pitchOffset, 0);
|
||||
Matrix.multiplyMM(modelViewProjection, 0, view, 0, camera, 0);
|
||||
Matrix.translateM(openGL.view, 0, 0, pitchOffset, 0);
|
||||
Matrix.multiplyMM(openGL.modelViewProjection, 0, openGL.view, 0, openGL.camera, 0);
|
||||
|
||||
// Prepare the triangle coordinate data
|
||||
GLES20.glVertexAttribPointer(positionParam, 3, GLES20.GL_FLOAT, false, 0, vertexBuffer);
|
||||
GLES20.glVertexAttribPointer(openGL.positionParam, 3, GLES20.GL_FLOAT, false, 0, openGL.vertexBuffer);
|
||||
}
|
||||
|
||||
// Prepare the texturecoordinates
|
||||
GLES20.glVertexAttribPointer(texCoordParam, 2, GLES20.GL_FLOAT, false, 0, uvBuffer);
|
||||
GLES20.glVertexAttribPointer(openGL.texCoordParam, 2, GLES20.GL_FLOAT, false, 0, openGL.uvBuffer);
|
||||
|
||||
// Apply the projection and view transformation
|
||||
GLES20.glUniformMatrix4fv(modelViewProjectionParam, 1, false, modelViewProjection, 0);
|
||||
GLES20.glUniformMatrix4fv(openGL.modelViewProjectionParam, 1, false, openGL.modelViewProjection, 0);
|
||||
|
||||
// Bind texture to fbo's color texture
|
||||
GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
|
||||
|
@ -551,14 +424,14 @@ public class MainActivity
|
|||
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, splashTexture[0]);
|
||||
}
|
||||
else {
|
||||
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, fbo.ColorTexture[0]);
|
||||
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, openGL.fbo.ColorTexture[0]);
|
||||
}
|
||||
|
||||
// Set the sampler texture unit to our fbo's color texture
|
||||
GLES20.glUniform1i(samplerParam, 0);
|
||||
GLES20.glUniform1i(openGL.samplerParam, 0);
|
||||
|
||||
// Draw the triangles
|
||||
GLES20.glDrawElements(GLES20.GL_TRIANGLES, 6, GLES20.GL_UNSIGNED_SHORT, listBuffer);
|
||||
GLES20.glDrawElements(GLES20.GL_TRIANGLES, 6, GLES20.GL_UNSIGNED_SHORT, openGL.listBuffer);
|
||||
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, activeTex0.get(0));
|
||||
}
|
||||
}
|
||||
|
@ -577,6 +450,18 @@ public class MainActivity
|
|||
public void onCardboardTrigger() {
|
||||
Log.i(TAG, "onCardboardTrigger");
|
||||
|
||||
if (!mShowingSpashScreen && mWADChooser.choosingWAD())
|
||||
{
|
||||
if (eulerAngles[1] / (M_PI / 180.0f) > 15.0f)
|
||||
mWADChooser.MoveNext();
|
||||
else if (eulerAngles[1] / (M_PI / 180.0f) < -15.0f)
|
||||
mWADChooser.MovePrev();
|
||||
else
|
||||
mWADChooser.SelectWAD();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (System.currentTimeMillis() - triggerTimeout > 200) {
|
||||
|
||||
if (mDVRInitialised) {
|
||||
|
@ -592,13 +477,6 @@ public class MainActivity
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
public int getCharacter(int keyCode, KeyEvent event)
|
||||
{
|
||||
if (keyCode==KeyEvent.KEYCODE_DEL) return '\b';
|
||||
return event.getUnicodeChar();
|
||||
}
|
||||
|
||||
private void dismissSplashScreen()
|
||||
{
|
||||
if (mShowingSpashScreen) {
|
||||
|
@ -613,6 +491,30 @@ public class MainActivity
|
|||
int keyCode = event.getKeyCode();
|
||||
int action = event.getAction();
|
||||
|
||||
if (!mShowingSpashScreen &&
|
||||
mWADChooser.choosingWAD())
|
||||
{
|
||||
if (action == KeyEvent.ACTION_UP &&
|
||||
keyCode == KeyEvent.KEYCODE_BUTTON_A) {
|
||||
if (eulerAngles[1] / (M_PI / 180.0f) > 10.0f)
|
||||
mWADChooser.MoveNext();
|
||||
else if (eulerAngles[1] / (M_PI / 180.0f) < -10.0f)
|
||||
mWADChooser.MovePrev();
|
||||
else
|
||||
mWADChooser.SelectWAD();
|
||||
}
|
||||
else if (action == KeyEvent.ACTION_UP &&
|
||||
keyCode == KeyEvent.KEYCODE_DPAD_LEFT) {
|
||||
mWADChooser.MovePrev();
|
||||
}
|
||||
else if (action == KeyEvent.ACTION_UP &&
|
||||
keyCode == KeyEvent.KEYCODE_DPAD_RIGHT) {
|
||||
mWADChooser.MoveNext();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
if ( action != KeyEvent.ACTION_DOWN && action != KeyEvent.ACTION_UP )
|
||||
{
|
||||
return super.dispatchKeyEvent( event );
|
||||
|
@ -744,35 +646,6 @@ public class MainActivity
|
|||
return (axisValue > axisValue2) ? axisValue : axisValue2;
|
||||
}
|
||||
|
||||
public void SetupUVCoords()
|
||||
{
|
||||
// The texture buffer
|
||||
ByteBuffer bb = ByteBuffer.allocateDirect(uvs.length * 4);
|
||||
bb.order(ByteOrder.nativeOrder());
|
||||
uvBuffer = bb.asFloatBuffer();
|
||||
uvBuffer.put(uvs);
|
||||
uvBuffer.position(0);
|
||||
}
|
||||
|
||||
public void SetupTriangle(int x, int y, int width, int height)
|
||||
{
|
||||
// We have to create the vertices of our triangle.
|
||||
vertices = new float[]
|
||||
{
|
||||
x, y, 0.0f,
|
||||
x, y + height, 0.0f,
|
||||
x + width, y + height, 0.0f,
|
||||
x + width, y, 0.0f,
|
||||
};
|
||||
|
||||
// The vertex buffer.
|
||||
ByteBuffer bb = ByteBuffer.allocateDirect(vertices.length * 4);
|
||||
bb.order(ByteOrder.nativeOrder());
|
||||
vertexBuffer = bb.asFloatBuffer();
|
||||
vertexBuffer.put(vertices);
|
||||
vertexBuffer.position(0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the menu
|
||||
*/
|
||||
|
@ -860,22 +733,13 @@ public class MainActivity
|
|||
mDoomHeight = h;
|
||||
mDoomBitmap = Bitmap.createBitmap(w, h, Bitmap.Config.RGB_565);
|
||||
|
||||
CreateFBO(fbo, mDoomWidth, mDoomHeight);
|
||||
openGL.SetBitmap(mDoomBitmap);
|
||||
openGL.CreateFBO(mDoomWidth, mDoomHeight);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void OnFatalError(final String text) {
|
||||
MessageBox("Fatal Error", "Doom has terminated. " + "Reason: "
|
||||
+ text);
|
||||
|
||||
try {
|
||||
Thread.sleep(10000);
|
||||
}
|
||||
catch (InterruptedException ie){
|
||||
}
|
||||
|
||||
// Must quit here or the LIB will crash
|
||||
DoomTools.hardExit(-1);
|
||||
Log.e(TAG, "ERROR: " + text);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
255
app/src/main/java/com/drbeef/dvr/OpenGL.java
Normal file
255
app/src/main/java/com/drbeef/dvr/OpenGL.java
Normal file
|
@ -0,0 +1,255 @@
|
|||
package com.drbeef.dvr;
|
||||
|
||||
|
||||
import android.content.pm.ActivityInfo;
|
||||
import android.content.res.AssetManager;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.BitmapFactory;
|
||||
import android.media.MediaPlayer;
|
||||
import android.opengl.GLES11Ext;
|
||||
import android.opengl.GLES20;
|
||||
import android.opengl.GLUtils;
|
||||
import android.opengl.Matrix;
|
||||
import android.os.Bundle;
|
||||
import android.util.Log;
|
||||
import android.view.Window;
|
||||
import android.view.WindowManager;
|
||||
|
||||
import com.google.vrtoolkit.cardboard.CardboardView;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.ByteOrder;
|
||||
import java.nio.FloatBuffer;
|
||||
import java.nio.ShortBuffer;
|
||||
|
||||
import javax.microedition.khronos.egl.EGLConfig;
|
||||
|
||||
public class OpenGL {
|
||||
|
||||
private static final int GL_RGBA8 = 0x8058;
|
||||
Bitmap mDoomBitmap;
|
||||
|
||||
public void SetBitmap(Bitmap bmp)
|
||||
{
|
||||
mDoomBitmap = bmp;
|
||||
}
|
||||
|
||||
public void onCreate() {
|
||||
modelScreen = new float[16];
|
||||
camera = new float[16];
|
||||
view = new float[16];
|
||||
modelViewProjection = new float[16];
|
||||
modelView = new float[16];
|
||||
|
||||
//Create the FBOs
|
||||
fbo = new DVRFBO();
|
||||
}
|
||||
|
||||
public void onSurfaceCreated(EGLConfig config) {
|
||||
Log.i("DVR", "onSurfaceCreated");
|
||||
|
||||
ByteBuffer bbVertices = ByteBuffer.allocateDirect(SCREEN_COORDS.length * 4);
|
||||
bbVertices.order(ByteOrder.nativeOrder());
|
||||
screenVertices = bbVertices.asFloatBuffer();
|
||||
screenVertices.put(SCREEN_COORDS);
|
||||
screenVertices.position(0);
|
||||
|
||||
// initialize byte buffer for the draw list
|
||||
ByteBuffer dlb = ByteBuffer.allocateDirect(indices.length * 2);
|
||||
dlb.order(ByteOrder.nativeOrder());
|
||||
listBuffer = dlb.asShortBuffer();
|
||||
listBuffer.put(indices);
|
||||
listBuffer.position(0);
|
||||
|
||||
// Create the shaders, images
|
||||
int vertexShader = loadShader(GLES20.GL_VERTEX_SHADER, vs_Image);
|
||||
int fragmentShader = loadShader(GLES20.GL_FRAGMENT_SHADER, fs_Image);
|
||||
|
||||
sp_Image = GLES20.glCreateProgram(); // create empty OpenGL ES Program
|
||||
GLES20.glAttachShader(sp_Image, vertexShader); // add the vertex shader to program
|
||||
GLES20.glAttachShader(sp_Image, fragmentShader); // add the fragment shader to program
|
||||
GLES20.glLinkProgram(sp_Image); // creates OpenGL ES program executable
|
||||
|
||||
positionParam = GLES20.glGetAttribLocation(sp_Image, "a_Position");
|
||||
texCoordParam = GLES20.glGetAttribLocation(sp_Image, "a_texCoord");
|
||||
modelViewProjectionParam = GLES20.glGetUniformLocation(sp_Image, "u_MVPMatrix");
|
||||
samplerParam = GLES20.glGetUniformLocation(sp_Image, "s_texture");
|
||||
|
||||
|
||||
GLES20.glEnableVertexAttribArray(positionParam);
|
||||
GLES20.glEnableVertexAttribArray(texCoordParam);
|
||||
|
||||
// Build the camera matrix
|
||||
Matrix.setLookAtM(camera, 0, 0.0f, 0.0f, 0.01f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f);
|
||||
}
|
||||
|
||||
void CopyBitmapToTexture(Bitmap bmp, int textureUnit)
|
||||
{
|
||||
// Bind texture to texturename
|
||||
GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
|
||||
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, textureUnit);
|
||||
|
||||
// Set filtering
|
||||
GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_LINEAR);
|
||||
GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_LINEAR);
|
||||
|
||||
// Set wrapping mode
|
||||
GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_S, GLES20.GL_CLAMP_TO_EDGE);
|
||||
GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_T, GLES20.GL_CLAMP_TO_EDGE);
|
||||
|
||||
// Load the bitmap into the bound texture.
|
||||
GLUtils.texImage2D(GLES20.GL_TEXTURE_2D, 0, bmp, 0);
|
||||
|
||||
//unbind
|
||||
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, 0);
|
||||
}
|
||||
|
||||
public void SetupUVCoords()
|
||||
{
|
||||
// The texture buffer
|
||||
ByteBuffer bb = ByteBuffer.allocateDirect(uvs.length * 4);
|
||||
bb.order(ByteOrder.nativeOrder());
|
||||
uvBuffer = bb.asFloatBuffer();
|
||||
uvBuffer.put(uvs);
|
||||
uvBuffer.position(0);
|
||||
}
|
||||
|
||||
public void SetupTriangle(int x, int y, int width, int height)
|
||||
{
|
||||
// We have to create the vertices of our triangle.
|
||||
vertices = new float[]
|
||||
{
|
||||
x, y, 0.0f,
|
||||
x, y + height, 0.0f,
|
||||
x + width, y + height, 0.0f,
|
||||
x + width, y, 0.0f,
|
||||
};
|
||||
|
||||
// The vertex buffer.
|
||||
ByteBuffer bb = ByteBuffer.allocateDirect(vertices.length * 4);
|
||||
bb.order(ByteOrder.nativeOrder());
|
||||
vertexBuffer = bb.asFloatBuffer();
|
||||
vertexBuffer.put(vertices);
|
||||
vertexBuffer.position(0);
|
||||
}
|
||||
|
||||
public FloatBuffer screenVertices;
|
||||
|
||||
public int positionParam;
|
||||
public int texCoordParam;
|
||||
public int samplerParam;
|
||||
public int modelViewProjectionParam;
|
||||
|
||||
public float[] modelScreen;
|
||||
public float[] camera;
|
||||
public float[] view;
|
||||
public float[] modelViewProjection;
|
||||
public float[] modelView;
|
||||
|
||||
public float screenDistance = 8f;
|
||||
public float screenScale = 4f;
|
||||
|
||||
public static final String vs_Image =
|
||||
"uniform mat4 u_MVPMatrix;" +
|
||||
"attribute vec4 a_Position;" +
|
||||
"attribute vec2 a_texCoord;" +
|
||||
"varying vec2 v_texCoord;" +
|
||||
"void main() {" +
|
||||
" gl_Position = u_MVPMatrix * a_Position;" +
|
||||
" v_texCoord = a_texCoord;" +
|
||||
"}";
|
||||
|
||||
|
||||
public static final String fs_Image =
|
||||
"precision mediump float;" +
|
||||
"varying vec2 v_texCoord;" +
|
||||
"uniform sampler2D s_texture;" +
|
||||
"void main() {" +
|
||||
" gl_FragColor = texture2D( s_texture, v_texCoord );" +
|
||||
"}";
|
||||
|
||||
public static int loadShader(int type, String shaderCode){
|
||||
int shader = GLES20.glCreateShader(type);
|
||||
GLES20.glShaderSource(shader, shaderCode);
|
||||
GLES20.glCompileShader(shader);
|
||||
return shader;
|
||||
}
|
||||
//FBO render eye buffer
|
||||
public DVRFBO fbo;
|
||||
|
||||
|
||||
boolean CreateFBO( int width, int height)
|
||||
{
|
||||
Log.d("DVR", "CreateFBO");
|
||||
// Create the color buffer texture.
|
||||
GLES20.glGenTextures(1, fbo.ColorTexture, 0);
|
||||
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, fbo.ColorTexture[0]);
|
||||
GLES20.glTexImage2D(GLES20.GL_TEXTURE_2D, 0, GL_RGBA8, width, height, 0, GLES20.GL_RGBA, GLES20.GL_UNSIGNED_BYTE, null);
|
||||
GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_S, GLES20.GL_CLAMP_TO_EDGE);
|
||||
GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_T, GLES20.GL_CLAMP_TO_EDGE);
|
||||
GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_LINEAR);
|
||||
GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_LINEAR);
|
||||
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, 0);
|
||||
|
||||
// Create depth buffer.
|
||||
GLES20.glGenRenderbuffers(1, fbo.DepthBuffer, 0);
|
||||
GLES20.glBindRenderbuffer(GLES20.GL_RENDERBUFFER, fbo.DepthBuffer[0]);
|
||||
GLES20.glRenderbufferStorage(GLES20.GL_RENDERBUFFER, GLES11Ext.GL_DEPTH_COMPONENT24_OES, width, height);
|
||||
GLES20.glBindRenderbuffer(GLES20.GL_RENDERBUFFER, 0);
|
||||
|
||||
// Create the frame buffer.
|
||||
GLES20.glGenFramebuffers(1, fbo.FrameBuffer, 0);
|
||||
GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, fbo.FrameBuffer[0]);
|
||||
GLES20.glFramebufferRenderbuffer(GLES20.GL_FRAMEBUFFER, GLES20.GL_DEPTH_ATTACHMENT, GLES20.GL_RENDERBUFFER, fbo.DepthBuffer[0]);
|
||||
GLES20.glFramebufferTexture2D(GLES20.GL_FRAMEBUFFER, GLES20.GL_COLOR_ATTACHMENT0, GLES20.GL_TEXTURE_2D, fbo.ColorTexture[0], 0);
|
||||
int renderFramebufferStatus = GLES20.glCheckFramebufferStatus(GLES20.GL_FRAMEBUFFER);
|
||||
GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, 0);
|
||||
if ( renderFramebufferStatus != GLES20.GL_FRAMEBUFFER_COMPLETE )
|
||||
{
|
||||
Log.d("DVR", "Incomplete frame buffer object!!");
|
||||
return false;
|
||||
}
|
||||
|
||||
fbo.width = width;
|
||||
fbo.height = height;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void DestroyFBO( )
|
||||
{
|
||||
GLES20.glDeleteFramebuffers( 1, fbo.FrameBuffer, 0 );
|
||||
fbo.FrameBuffer[0] = 0;
|
||||
GLES20.glDeleteRenderbuffers( 1, fbo.DepthBuffer, 0 );
|
||||
fbo.DepthBuffer[0] = 0;
|
||||
GLES20.glDeleteTextures( 1, fbo.ColorTexture, 0 );
|
||||
fbo.ColorTexture[0] = 0;
|
||||
fbo.width = 0;
|
||||
fbo.height = 0;
|
||||
}
|
||||
|
||||
// Geometric variables
|
||||
public static float vertices[];
|
||||
public static final short[] indices = new short[] {0, 1, 2, 0, 2, 3};
|
||||
public static final float uvs[] = new float[] {
|
||||
0.0f, 1.0f,
|
||||
0.0f, 0.0f,
|
||||
1.0f, 0.0f,
|
||||
1.0f, 1.0f
|
||||
};
|
||||
|
||||
public static final float[] SCREEN_COORDS = new float[] {
|
||||
-1.3f, -1.0f, 1.0f,
|
||||
-1.3f, 1.0f, 1.0f,
|
||||
1.3f, 1.0f, 1.0f,
|
||||
1.3f, -1.0f, 1.0f
|
||||
};
|
||||
|
||||
public FloatBuffer vertexBuffer;
|
||||
public ShortBuffer listBuffer;
|
||||
public FloatBuffer uvBuffer;
|
||||
|
||||
//Shader Program
|
||||
public static int sp_Image;
|
||||
}
|
|
@ -1,14 +1,162 @@
|
|||
package com.drbeef.dvr;
|
||||
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Paint;
|
||||
import android.opengl.GLES20;
|
||||
import android.opengl.Matrix;
|
||||
|
||||
import com.google.vrtoolkit.cardboard.Eye;
|
||||
|
||||
import java.io.File;
|
||||
import java.nio.IntBuffer;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import doom.util.DoomTools;
|
||||
import doom.util.Natives;
|
||||
|
||||
/**
|
||||
* Created by Simon on 04/03/2016.
|
||||
*/
|
||||
public class WADChooser {
|
||||
|
||||
static String wad = "doom.wad";
|
||||
OpenGL openGL = null;
|
||||
|
||||
public static String GetChosenWAD()
|
||||
List<String> wads = new ArrayList<String>();
|
||||
private int selectedWAD = 0;
|
||||
|
||||
WADChooser(OpenGL openGL) {
|
||||
this.openGL = openGL;
|
||||
|
||||
File[] files = new File(DoomTools.GetDVRFolder()).listFiles();
|
||||
|
||||
for (File file : files) {
|
||||
if (file.isFile() &&
|
||||
file.getName().toUpperCase().compareTo("PRBOOM.WAD") != 0 &&
|
||||
file.getName().toUpperCase().endsWith("WAD"))
|
||||
wads.add(file.getName());
|
||||
}
|
||||
|
||||
//No point choosing a wad if there's only one!
|
||||
if (wads.size() == 1) mChoosingWAD = false;
|
||||
}
|
||||
|
||||
private boolean mChoosingWAD = true;
|
||||
|
||||
public boolean choosingWAD() {
|
||||
return mChoosingWAD;
|
||||
}
|
||||
|
||||
public void SelectWAD()
|
||||
{
|
||||
return wad;
|
||||
mChoosingWAD = false;
|
||||
}
|
||||
|
||||
public String GetChosenWAD() {
|
||||
return wads.get(selectedWAD);
|
||||
}
|
||||
|
||||
public void MoveNext()
|
||||
{
|
||||
selectedWAD++;
|
||||
if (selectedWAD == wads.size())
|
||||
selectedWAD = 0;
|
||||
}
|
||||
|
||||
public void MovePrev()
|
||||
{
|
||||
selectedWAD--;
|
||||
if (selectedWAD < 0)
|
||||
selectedWAD = wads.size()-1;
|
||||
}
|
||||
|
||||
void DrawWADName()
|
||||
{
|
||||
// Create an empty, mutable bitmap
|
||||
Bitmap bitmap = Bitmap.createBitmap(256, 256, Bitmap.Config.ARGB_4444);
|
||||
// get a canvas to paint over the bitmap
|
||||
Canvas canvas = new Canvas(bitmap);
|
||||
bitmap.eraseColor(0);
|
||||
|
||||
// get a background image from resources
|
||||
// note the image format must match the bitmap format
|
||||
// Drawable background = context.getResources().getDrawable(R.drawable.background);
|
||||
// background.setBounds(0, 0, 256, 256);
|
||||
// background.draw(canvas); // draw the background to our bitmap
|
||||
|
||||
// Draw the text
|
||||
Paint textPaint = new Paint();
|
||||
textPaint.setTextSize(20);
|
||||
|
||||
textPaint.setAntiAlias(true);
|
||||
textPaint.setARGB(0xff, 0xff, 0x20, 0x00);
|
||||
// draw the text centered
|
||||
canvas.drawText("Choose WAD:", 16, 60, textPaint);
|
||||
canvas.drawText("<- " + GetChosenWAD() + " ->", 16, 112, textPaint);
|
||||
|
||||
openGL.CopyBitmapToTexture(bitmap, openGL.fbo.ColorTexture[0]);
|
||||
}
|
||||
|
||||
public void onDrawEye(Eye eye) {
|
||||
|
||||
DrawWADName();
|
||||
|
||||
GLES20.glEnable(GLES20.GL_SCISSOR_TEST);
|
||||
GLES20.glScissor(eye.getViewport().x, eye.getViewport().y,
|
||||
eye.getViewport().width, eye.getViewport().height);
|
||||
GLES20.glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
|
||||
GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT | GLES20.GL_DEPTH_BUFFER_BIT);
|
||||
|
||||
GLES20.glViewport(eye.getViewport().x,
|
||||
eye.getViewport().y,
|
||||
eye.getViewport().width,
|
||||
eye.getViewport().height);
|
||||
|
||||
//Clear the viewport
|
||||
GLES20.glEnable(GLES20.GL_SCISSOR_TEST);
|
||||
GLES20.glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
|
||||
GLES20.glScissor(eye.getViewport().x,
|
||||
eye.getViewport().y,
|
||||
eye.getViewport().width,
|
||||
eye.getViewport().height);
|
||||
GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT);
|
||||
|
||||
GLES20.glUseProgram(openGL.sp_Image);
|
||||
|
||||
// Apply the eye transformation to the camera.
|
||||
Matrix.multiplyMM(openGL.view, 0, eye.getEyeView(), 0, openGL.camera, 0);
|
||||
|
||||
// Build the ModelView and ModelViewProjection matrices
|
||||
// for calculating screen position.
|
||||
float[] perspective = eye.getPerspective(0.1f, 100.0f);
|
||||
|
||||
// Object first appears directly in front of user.
|
||||
Matrix.setIdentityM(openGL.modelScreen, 0);
|
||||
Matrix.translateM(openGL.modelScreen, 0, 0, 0, -openGL.screenDistance);
|
||||
Matrix.scaleM(openGL.modelScreen, 0, openGL.screenScale, openGL.screenScale, 1.0f);
|
||||
Matrix.multiplyMM(openGL.modelView, 0, openGL.view, 0, openGL.modelScreen, 0);
|
||||
Matrix.multiplyMM(openGL.modelViewProjection, 0, perspective, 0, openGL.modelView, 0);
|
||||
GLES20.glVertexAttribPointer(openGL.positionParam, 3, GLES20.GL_FLOAT, false, 0, openGL.screenVertices);
|
||||
|
||||
// Prepare the texturecoordinates
|
||||
GLES20.glVertexAttribPointer(openGL.texCoordParam, 2, GLES20.GL_FLOAT, false, 0, openGL.uvBuffer);
|
||||
|
||||
// Apply the projection and view transformation
|
||||
GLES20.glUniformMatrix4fv(openGL.modelViewProjectionParam, 1, false, openGL.modelViewProjection, 0);
|
||||
|
||||
// Bind texture to fbo's color texture
|
||||
GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
|
||||
IntBuffer activeTex0 = IntBuffer.allocate(2);
|
||||
GLES20.glGetIntegerv(GLES20.GL_TEXTURE_BINDING_2D, activeTex0);
|
||||
|
||||
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, openGL.fbo.ColorTexture[0]);
|
||||
|
||||
// Set the sampler texture unit to our fbo's color texture
|
||||
GLES20.glUniform1i(openGL.samplerParam, 0);
|
||||
|
||||
// Draw the triangles
|
||||
GLES20.glDrawElements(GLES20.GL_TRIANGLES, 6, GLES20.GL_UNSIGNED_SHORT, openGL.listBuffer);
|
||||
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, activeTex0.get(0));
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue