Changes to submit NOMADGearVR to Oculus Store and to update to latest

NOMADVRLib
Add missing initialization to rply, add NOMAD License to rply.
parent 52e7546f
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.lrz.NOMADGearvrT"
android:versionCode="1"
android:versionName="1.0" >
android:versionCode="2"
android:versionName="1.0"
android:installLocation="auto"
>
<uses-sdk android:minSdkVersion="21" android:targetSdkVersion="21" />
<!-- Allow reading of the appropriate lens distortion file for the device. -->
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
......@@ -16,7 +19,7 @@
<uses-feature android:name="android.hardware.usb.host" />
<!-- Tell the system this app requires OpenGL ES 3.0. -->
<!--rgh: For tesselation, we need 3.2-->
<uses-feature android:glEsVersion="0x00030002" android:required="true" />
<uses-feature android:glEsVersion="0x00030001" android:required="true" />
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
......@@ -30,7 +33,8 @@
android:label="@string/app_name"
android:launchMode="singleTask"
android:screenOrientation="landscape"
android:configChanges="orientation|screenSize|keyboard|keyboardHidden">
android:configChanges= "screenSize|screenLayout|orientation|keyboardHidden|keyboard|navigation"
android:excludeFromRecents="true">
<!--Test opening a NOMAD url-->
<intent-filter>
<action android:name="android.intent.action.VIEW" />
......@@ -49,9 +53,10 @@
android:mimeType="application/octet-stream"/>
</intent-filter>
<!-- This filter lets the apk show up as a launchable icon -->
<!-- rgh: hiding as only the gearvrchooser should be shown -->
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
<category android:name="android.intent.category.INFO" />
</intent-filter>
</activity>
</application>
......
......@@ -15,6 +15,8 @@ android {
defaultConfig {
minSdkVersion 21
targetSdkVersion 21
versionCode 2
versionName "0.2"
}
sourceSets {
......
......@@ -14,7 +14,10 @@ LOCAL_SRC_FILES := ../../../Src/OvrApp.cpp ../../../Src/rply/rply.c \
../../../Src/NOMADVRLib/UnitCellShaders.cpp \
../../../Src/NOMADVRLib/polyhedron.cpp \
../../../Src/NOMADVRLib/IsosurfacesGL.cpp \
../../../Src/NOMADVRLib/IsoShaders.cpp
../../../Src/NOMADVRLib/IsoShaders.cpp \
../../../Src/NOMADVRLib/grid.cpp \
../../../Src/NOMADVRLib/markerShaders.cpp
LOCAL_STATIC_LIBRARIES := vrsound vrmodel vrlocale vrgui vrappframework systemutils libovrkernel
LOCAL_SHARED_LIBRARIES := vrapi
......
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">NOMADGearvrT</string>
<string name="app_name">NOMAD GearVR</string>
<string name="action_settings">Settings</string>
<string name="hello_world">Hello world!</string>
......
package oculus;
//This file is the same, except for the package above, as
//NOMADgvrT\src\main\java\com\google\vr\ndk\samples\treasurehunt\Filepath.java
//https://stackoverflow.com/questions/3401579/get-filename-and-path-from-uri-from-mediastore/7265235#7265235
class Filepath {
//@SuppressLint("NewApi")
public static String getFilePath(android.content.Context context, android.net.Uri uri) throws java.net.URISyntaxException {
String selection = null;
String[] selectionArgs = null;
// Uri is different in versions after KITKAT (Android 4.4), we need to
if (android.os.Build.VERSION.SDK_INT >= 19 && android.provider.DocumentsContract.isDocumentUri(context.getApplicationContext(), uri)) {
if (isExternalStorageDocument(uri)) {
final String docId = android.provider.DocumentsContract.getDocumentId(uri);
final String[] split = docId.split(":");
return android.os.Environment.getExternalStorageDirectory() + "/" + split[1];
} else if (isDownloadsDocument(uri)) {
final String id = android.provider.DocumentsContract.getDocumentId(uri);
uri = android.content.ContentUris.withAppendedId(
android.net.Uri.parse("content://downloads/public_downloads"), Long.valueOf(id));
} else if (isMediaDocument(uri)) {
final String docId = android.provider.DocumentsContract.getDocumentId(uri);
final String[] split = docId.split(":");
final String type = split[0];
if ("image".equals(type)) {
uri = android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
} else if ("video".equals(type)) {
uri = android.provider.MediaStore.Video.Media.EXTERNAL_CONTENT_URI;
} else if ("audio".equals(type)) {
uri = android.provider.MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
}
selection = "_id=?";
selectionArgs = new String[]{
split[1]
};
}
}
if ("content".equalsIgnoreCase(uri.getScheme())) {
String[] projection = {
android.provider.MediaStore.Images.Media.DATA
};
android.database.Cursor cursor = null;
try {
cursor = context.getContentResolver()
.query(uri, projection, selection, selectionArgs, null);
int column_index = cursor.getColumnIndexOrThrow(android.provider.MediaStore.Images.Media.DATA);
if (cursor.moveToFirst()) {
return cursor.getString(column_index);
}
} catch (Exception e) {
}
} else if ("file".equalsIgnoreCase(uri.getScheme())) {
return uri.getPath();
}
return null;
}
public static boolean isExternalStorageDocument(android.net.Uri uri) {
return "com.android.externalstorage.documents".equals(uri.getAuthority());
}
public static boolean isDownloadsDocument(android.net.Uri uri) {
return "com.android.providers.downloads.documents".equals(uri.getAuthority());
}
public static boolean isMediaDocument(android.net.Uri uri) {
return "com.android.providers.media.documents".equals(uri.getAuthority());
}
}
......@@ -25,49 +25,82 @@ public class MainActivity extends VrActivity {
System.loadLibrary("ovrapp");
}
public static native long nativeSetAppInterface( VrActivity act, String fromPackageNameString, String commandString, String uriString );
//http://stackoverflow.com/questions/8854359/exception-open-failed-eacces-permission-denied-on-android
// Storage Permissions
private static final int REQUEST_EXTERNAL_STORAGE = 1;
private static String[] PERMISSIONS_STORAGE = {
android.Manifest.permission.READ_EXTERNAL_STORAGE,
android.Manifest.permission.WRITE_EXTERNAL_STORAGE
};
/**
* Checks if the app has permission to write to device storage
*
* If the app does not has permission then the user will be prompted to grant permissions
*
* @param activity
*/
public static void verifyStoragePermissions(android.app.Activity activity) {
// Check if we have write permission
/* int permission = android.support.v4.app.ActivityCompat.checkSelfPermission(activity, android.Manifest.permission.WRITE_EXTERNAL_STORAGE);
if (permission != android.content.pm.PackageManager.PERMISSION_GRANTED) {
// We don't have permission so prompt the user
android.support.v4.app.ActivityCompat.requestPermissions(
activity,
PERMISSIONS_STORAGE,
REQUEST_EXTERNAL_STORAGE
);
}*/
}
public static native long nativeSetAppInterface( VrActivity act, String fromPackageNameString, String commandString, String uriString );
/*
@Override
protected void onActivityResult(int requestCode, int resultCode, android.content.Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if(requestCode==123 && resultCode==RESULT_OK) {
String s=data.getDataString();
android.util.Log.d("NOMADGearvrT","OnActivityResult, s="+s);
String uriString="";
if (s.startsWith("file://")) {
uriString=s.substring(7);
} else if (s.startsWith("content://com.asus.filemanager.OpenFileProvider/file")) {
uriString=s.substring(52);
} else {
android.net.Uri u=android.net.Uri.parse(s);
try {
uriString=Filepath.getFilePath (this.getApplicationContext(), u);
} catch (java.net.URISyntaxException e) {
android.util.Log.d("NOMADgvrT","URISyntaxException, e="+e);
uriString=null;
}
}
android.util.Log.d("NOMADgvrT","OnActivityResult, uri="+uriString);
nativeSetConfigFile(uriString, android.os.Environment.getExternalStorageDirectory().getPath() + "/");
nativeLoadConfigFile(nativeTreasureHuntRenderer);
}
}
*/
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
verifyStoragePermissions(this);
Intent intent = getIntent();
String commandString = VrActivity.getCommandStringFromIntent( intent );
String fromPackageNameString = VrActivity.getPackageStringFromIntent( intent );
String uriString = VrActivity.getUriStringFromIntent( intent );
//rgh: if intent, save to tmp file and pass it over
if (uriString.startsWith("content://")) {
//http://stackoverflow.com/questions/14364091/retrieve-file-path-from-caught-downloadmanager-intent
//http://stackoverflow.com/questions/1477269/write-a-binary-downloaded-file-to-disk-in-java
//http://stackoverflow.com/questions/4864875/folder-for-temporary-files-creation-in-android-why-does-data-local-tmp-doesnt
uriString="file:///data/local/tmp/material.ncfg";
try {
java.io.InputStream input = getContentResolver().openInputStream(intent.getData());
byte[] buffer = new byte[8 * 1024];
java.io.FileOutputStream output = new java.io.FileOutputStream("/data/local/tmp/material.ncfg");
try{
int bytesRead;
while((bytesRead = input.read()) != -1){
output.write(buffer, 0, bytesRead);
}
} finally {
try{
output.close();
} catch (Exception e) {
uriString="error";
}
try {
input.close();
} catch (java.io.IOException e) {
uriString="error";
}
}
} catch (java.io.IOException e) {
uriString="error";
}
String uriString = VrActivity.getUriStringFromIntent( intent );
android.net.Uri u=android.net.Uri.parse(uriString);
try {
uriString=Filepath.getFilePath (this.getApplicationContext(), u);
} catch (java.net.URISyntaxException e) {
android.util.Log.d("NOMADgvrT","URISyntaxException, e="+e);
uriString=null;
}
setAppPtr( nativeSetAppInterface( this, fromPackageNameString, commandString, uriString ) );
}
}
......@@ -34,7 +34,7 @@ void eprintf( const char *fmt, ... )
vsprintf( buffer, fmt, args );
va_end( args );
LOG("Error in NOMADGearvrT");
LOG("Message from NOMADGearvrT");
if (*fmt=='\0')
LOG("Empty format");
LOG("<%s>", buffer);
......@@ -105,33 +105,55 @@ void OvrApp::OneTimeInit( const char * fromPackage, const char * launchIntentJSO
OVR_UNUSED( fromPackage );
OVR_UNUSED( launchIntentJSON );
LOG("OneTimeInit, launchintentURI");
LOG("NOMADGearVRT, OneTimeInit, launchintentURI");
LOG(launchIntentURI);
LOG("launchIntentURI==null");
LOG("NOMADGearVRT, launchIntentURI==null");
LOG("%d", launchIntentURI==nullptr);
//LOG("length of launchIntentURI=%d", strlen(launchIntentURI));
//for (unsigned int i=0;i<strlen(launchIntentURI);i++) {
// LOG("<%c>: [%d]", launchIntentURI[i], launchIntentURI[i]);
//}
const char *defaultURI="file:///sdcard/Oculus/NOMAD/ViveTDefault.ncfg";
//open a default file if none given
if (!launchIntentURI || !strcmp(launchIntentURI, "")) {
LOG(" OneTimeInit changing launchIntentURI");
launchIntentURI=defaultURI;
const char *configLocation="/sdcard/NOMAD/NOMADGearVR.cfg";
const char *defaultURI="/sdcard/Oculus/NOMAD/ViveTDefault.ncfg";
char finalURI[1024];
FILE *cl = fopen (configLocation, "r");
if (cl==nullptr) {
LOG("NOMADGearVRT, /sdcard/NOMAD/NOMADGearVR.cfg not found, using default at /sdcard/Oculus/NOMAD/ViveTDefault.ncfg");
strcpy(finalURI, defaultURI);
} else {
fgets(finalURI, 1024, cl);
//discard newline
int l=strlen(finalURI);
if (finalURI[l-1]=='\n')
finalURI[l-1]='\0';
LOG("NOMADGearVRT, /sdcard/NOMAD/NOMADGearVR.cfg found, using contents=%s", finalURI);
fclose (cl);
}
LOG("OneTimeInit, launchintentURI");
//open a default file if none given
//if (!launchIntentURI || !strcmp(launchIntentURI, "")) {
// LOG(" OneTimeInit changing launchIntentURI");
// launchIntentURI=finalURI;
//}
LOG("NOMADGearVRT OneTimeInit, launchintentURI");
LOG(launchIntentURI);
const char *configfile=launchIntentURI+6; //discard file://
const char *configfile=finalURI;
//change cwd so that relative paths work
std::string s(configfile);
chdir(s.substr(0, s.find_last_of("\\/")).c_str());
LOG("NOMADGEARVRT, configfile=%s", configfile);
int r;
LOG("OneTimeInit, 8");
LOG("NOMADGearVRT OneTimeInit, 8");
if ((r=loadConfigFile(configfile))<0) {
if (-100<r) {
eprintf(loadConfigFileErrors[-r]);
......@@ -150,7 +172,7 @@ void OvrApp::OneTimeInit( const char * fromPackage, const char * launchIntentJSO
}
if (!solid) {
LOG("No atom glyph specified, using Icosahedron");
LOG("NOMADGearVRT No atom glyph specified, using Icosahedron");
solid=new Solid(Solid::Type::Icosahedron);
}
LOG("OneTimeInit, 2");
......@@ -185,7 +207,7 @@ LOG("OneTimeInit, 4");
//rgh: for now, we don't have any tess-ready phones
//if (!PrepareAtomShader(&AtomsP, &AtomMatrixLoc)) {
hasTess=false;
if (!PrepareAtomShaderNoTess(&AtomsP, &AtomMatrixLoc))
if (!PrepareAtomShaderNoTess(&AtomsP, &AtomMatrixLoc, &TotalatomsLoc))
eprintf ("PrepareAtomShaderNoTess failed");
//};
//LOG("OneTimeInit, 7");
......@@ -197,7 +219,7 @@ LOG("OneTimeInit, 4");
if (e!=GL_NO_ERROR)
eprintf ("atomTexture error %d", e);
//LOG("OneTimeInit, 7A");
e=SetupAtoms(&AtomTVAO, &AtomTBuffer);
e=SetupAtoms(&AtomTVAO, &AtomTBuffer, &BondIndices);
if (e!=GL_NO_ERROR)
eprintf ("SetupAtoms error %d", e);
//LOG("OneTimeInit, 7B");
......@@ -213,6 +235,15 @@ LOG("OneTimeInit, 4");
if (ISOS) {
PrepareISOShader(&ISOP, &ISOMatrixLoc);
float m=BACKGROUND[0];
m=std::max(m, BACKGROUND[1]);
m=std::max(m, BACKGROUND[2]);
if (m>0.2f) { //make background darker, preserving colour, so additive blending works
for (int i=0;i<3;i++)
BACKGROUND[i]*=0.2f / m;
}
std::vector<float> vertices;
#ifndef INDICESGL32
std::vector<short> indices;
......@@ -236,10 +267,40 @@ LOG("OneTimeInit, 4");
for (int p = 0; p < TIMESTEPS*ISOS; p++) {
sprintf(tmpname, "%s%d-%s.ply", PATH, timestep,
plyfiles[p % ISOS]);
Matrix4f matFinal=Matrix4f::RotationX(-M_PI_2) *
Matrix4f matFinal;
/*matFinal=Matrix4f::RotationX(-M_PI_2) *
Matrix4f::Translation(translations[p%ISOS][0],
translations[p%ISOS][1],
translations[p%ISOS][2]);
*/
//gvr
if (voxelSize[0]!=-1) {
Matrix4f mvs, abcm, matcubetrans, sctrans, sc;
mvs=Matrix4f::Scaling(scaling/(float)voxelSize[0], scaling/(float)voxelSize[1],
scaling/(float)voxelSize[2]);
matcubetrans=Matrix4f::Translation(cubetrans[0], cubetrans[1], cubetrans[2]);
for (int i=0;i<3;i++) {
for(int j=0;j<3;j++)
abcm.M[i][j]=abc[i][j];
abcm.M[i][3]=0;
}
abcm.M[4][4]=1;
sc=Matrix4f::Scaling(supercell[0], supercell[1], supercell[2]);
sctrans=Matrix4f::Translation(-translations[p%ISOS][2],
-translations[p%ISOS][1], -translations[p%ISOS][0]);
matFinal = abcm*sctrans*sc*mvs;
} else {
matFinal=Matrix4f::Translation(translations[p%ISOS][0], translations[p%ISOS][1],
translations[p%ISOS][2]);
matFinal=Matrix4f::Scaling(scaling)*matFinal;
}
//end gvr
float t[16];
for (int i=0;i<4;i++)
for (int j=0;j<4;j++)
......@@ -295,7 +356,7 @@ void OvrApp::OneTimeShutdown()
bool OvrApp::OnKeyEvent( const int keyCode, const int repeatCount, const KeyEventType eventType )
{
animateTimesteps=!animateTimesteps;
eprintf("OnKeyEvent called!");
//eprintf("OnKeyEvent called! keycode=%d", keyCode);
return true;
/*if ( GuiSys->OnKeyEvent( keyCode, repeatCount, eventType ) )
{
......@@ -306,7 +367,7 @@ bool OvrApp::OnKeyEvent( const int keyCode, const int repeatCount, const KeyEven
Matrix4f OvrApp::Frame( const VrFrame & vrFrame )
{
LOG("Start Frame");
LOG("NOMADGearVRT Start Frame");
CenterEyeViewMatrix = vrapi_GetCenterEyeViewMatrix( &app->GetHeadModelParms(), &vrFrame.Tracking, NULL );
if (animateTimesteps) {
......@@ -316,7 +377,7 @@ Matrix4f OvrApp::Frame( const VrFrame & vrFrame )
currentSet++;
if (currentSet>TIMESTEPS-1)
currentSet=0;
LOG("currentSet updated, animate timesteps %d", currentSet);
LOG("NOMADGearVRT currentSet updated, animate timesteps %d", currentSet);
}
}
Matrix4f rot;
......@@ -359,7 +420,8 @@ void OvrApp::RenderIsos(const OVR::Matrix4f eyeViewProjection, int iso) {
GLenum e;
Matrix4f trans=Matrix4f::Translation(UserTranslation[0], UserTranslation[1], UserTranslation[2]);
//trans.translate(iPos).rotateX(-90).translate(UserPosition);
Matrix4f transform = eyeViewProjection*trans*Matrix4f::Scaling(0.2);
//rgh: prescaled on ply load
Matrix4f transform = eyeViewProjection*trans/**Matrix4f::Scaling(scaling)*/*Matrix4f::RotationX(-M_PI_2);
float t[16];
for (int i=0;i<4;i++)
for (int j=0;j<4;j++)
......@@ -367,7 +429,7 @@ void OvrApp::RenderIsos(const OVR::Matrix4f eyeViewProjection, int iso) {
glUseProgram(ISOP);
if ((e = glGetError()) != GL_NO_ERROR)
eprintf("1 Gl error RenderIsos timestep =%d: %d\n", currentSet, e);
glUniformMatrix4fv(ISOMatrixLoc, 1, GL_FALSE, t);
glUniformMatrix4fv(ISOMatrixLoc, 1, GL_FALSE, t);
if ((e = glGetError()) != GL_NO_ERROR)
eprintf("2 Gl error RenderIsos timestep =%d: %d\n", currentSet, e);
......@@ -380,13 +442,17 @@ glUniformMatrix4fv(ISOMatrixLoc, 1, GL_FALSE, t);
if ((e = glGetError()) != GL_NO_ERROR)
eprintf("4 Gl error RenderIsos timestep =%d: %d\n", currentSet, e);
} else {
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE);
glDepthMask(GL_FALSE);
for (int i=0;i<ISOS;i++) {
//rgh FIXME, redo this when we have the new rendering code for atom trajectories
glBindVertexArray(ISOVAO[currentSet*ISOS+i]);
glBindBuffer(GL_ARRAY_BUFFER, ISOBuffer[currentSet*ISOS+i]);
glBindBuffer(GL_ARRAY_BUFFER, ISOBuffer[currentSet*ISOS+i]);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ISOIndices[currentSet*ISOS+i]);
glEnableVertexAttribArray(0);
glEnableVertexAttribArray(1);
glEnableVertexAttribArray(2);
glEnableVertexAttribArray(2);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 10*sizeof(float), (const void *)(0*sizeof(float)));
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 10*sizeof(float), (const void *)(3*sizeof(float)));
glVertexAttribPointer(2, 4, GL_FLOAT, GL_FALSE, 10*sizeof(float), (const void *)(6*sizeof(float)));
......@@ -397,7 +463,10 @@ glUniformMatrix4fv(ISOMatrixLoc, 1, GL_FALSE, t);
if ((e = glGetError()) != GL_NO_ERROR)
eprintf("6 Gl error RenderIsos timestep =%d: %d\n", currentSet, e);
}
glDisable(GL_BLEND);
glDepthMask(GL_TRUE);
}
glBindVertexArray(0);
}
......@@ -411,13 +480,15 @@ void OvrApp::RenderAtoms(const float *m) //m[16]
if (hasTess) {
//FIXME, unimplemented
LOG("FIXME, No Tess code for atoms yet!");
LOG("NOMADGearVRT FIXME, No Tess code for atoms yet!");
return;
} else { //no tess
glBindVertexArray(AtomVAO[0]);
glBindTexture(GL_TEXTURE_2D, textures[1]);
glUseProgram(AtomsP);
glUniformMatrix4fv(AtomMatrixLoc, 1, GL_FALSE, m);
glUniform1f(TotalatomsLoc, (float)getTotalAtomsInTexture());
if (currentSet==0) {
glDrawElements(GL_TRIANGLES, numAtoms[currentSet]* 3 * solid->nFaces,
#ifndef INDICESGL32
......@@ -463,21 +534,17 @@ if (!showTrajectories)
int e;
if (!AtomTVAO) {
LOG("RenderAtomTrajectoriesUnitCell, no atoms");
LOG("NOMADGearVRT RenderAtomTrajectoriesUnitCell, no atoms");
return;
}
glBindVertexArray(AtomTVAO[0]);
//glUseProgram(UnitCellP);
//glUniformMatrix4fv(m_nUnitCellMatrixLocation, 1, GL_FALSE, matrix);
float color[4]={1,0,0,1};
glUniform4fv(UnitCellColourLoc, 1, color);
glUniform4fv(UnitCellColourLoc, 1, atomtrajectorycolour);
if ((e = glGetError()) != GL_NO_ERROR)
eprintf("Gl error after glUniform4fv 2 RenderUnitCell: %d\n", e);
//glEnableVertexAttribArray(0);
//glDisableVertexAttribArray(1);
eprintf("Gl error after glUniform4fv 2 RenderAtomTrajectoriesUnitCell: %d\n", e);
//LOG("atomtrajectories.size()=%d", atomtrajectories.size());
//rgh FIXME, old code which does not work with large atom sets!
glBindBuffer(GL_ARRAY_BUFFER, AtomTBuffer[0]);
for (unsigned int i=0;i<atomtrajectories.size();i++) {
......@@ -505,7 +572,7 @@ void OvrApp::RenderUnitCell(const Matrix4f eyeViewProjection)
if (UnitCellVAO==0)
eprintf ("Error, Unit Cell VAO not loaded");
int e;
Matrix4f sc=Matrix4f::Scaling(scaling);
int p[3];
for (p[0]=0;p[0]<repetitions[0];(p[0])++)
for (p[1]=0;p[1]<repetitions[1];(p[1])++)
......@@ -513,58 +580,72 @@ void OvrApp::RenderUnitCell(const Matrix4f eyeViewProjection)
{
float delta[3];
GetDisplacement(p, delta);
Vector3f iPos(delta[0]+UserTranslation[0], delta[1]+UserTranslation[1], delta[2]+UserTranslation[2]);
//delta is in atom coordinates, need rotateX(-90)
Vector3f iPos(delta[0]+UserTranslation[0]/scaling, delta[2]+UserTranslation[1]/scaling,
-delta[1]+UserTranslation[2]/scaling);
Matrix4f trans=Matrix4f::Translation(iPos);
//trans.translate(iPos).rotateX(-90).translate(UserPosition);
Matrix4f transform = eyeViewProjection*trans;
Matrix4f transform = eyeViewProjection*sc*trans*Matrix4f::RotationX(-M_PI_2);
float t[16];
for (int i=0;i<4;i++)
for (int j=0;j<4;j++)
t[j*4+i]=transform.M[i][j];
glUseProgram(UnitCellP);
glUniformMatrix4fv(UnitCellMatrixLoc, 1, GL_FALSE, t);
if ((e = glGetError()) != GL_NO_ERROR)
if ((e = glGetError()) != GL_NO_ERROR)
eprintf("Gl error after glUniform4fv 1 RenderUnitCell: %d\n", e);
float color[4]={1,1,1,1};
glUniform4fv(UnitCellColourLoc, 1, color);
if ((e = glGetError()) != GL_NO_ERROR)
eprintf("Gl error after glUniform4fv 2 RenderUnitCell: %d\n", e);
glBindVertexArray(UnitCellVAO);
if ((e = glGetError()) != GL_NO_ERROR)
eprintf("Gl error after glBindVertexArray RenderUnitCell: %d\n", e);
glDrawElements(GL_LINES, 24, GL_UNSIGNED_INT, 0);
if ((e = glGetError()) != GL_NO_ERROR)
eprintf("Gl error after RenderUnitCell: %d\n", e);
if (displayunitcell) {
glUniform4fv(UnitCellColourLoc, 1, unitcellcolour);
if ((e = glGetError()) != GL_NO_ERROR)
eprintf("Gl error after glUniform4fv 2 RenderUnitCell: %d\n", e);
glBindVertexArray(UnitCellVAO);
if ((e = glGetError()) != GL_NO_ERROR)
eprintf("Gl error after glBindVertexArray RenderUnitCell: %d\n", e);
glDrawElements(GL_LINES, 24, GL_UNSIGNED_INT, 0);
if ((e = glGetError()) != GL_NO_ERROR)
eprintf("Gl error after RenderUnitCell: %d\n", e);
}
//atom trajectories