Commit 15f4da94 authored by Ruben Jesus Garcia Hernandez's avatar Ruben Jesus Garcia Hernandez
Browse files

First version of GearVR Timestep viewer

parent 597b7853
#include <stdio.h>
#include "MyGL.h"
#include "eprintf.h"
GLuint CompileGLShader( const char *pchShaderName, const char *pchVertexShader, const char *pchFragmentShader,
const char *pchTessEvalShader /*= nullptr*/)
{
GLuint unProgramID = glCreateProgram();
GLuint nSceneVertexShader = glCreateShader(GL_VERTEX_SHADER);
glShaderSource( nSceneVertexShader, 1, &pchVertexShader, nullptr);
glCompileShader( nSceneVertexShader );
GLint vShaderCompiled = GL_FALSE;
glGetShaderiv( nSceneVertexShader, GL_COMPILE_STATUS, &vShaderCompiled);
if ( vShaderCompiled != GL_TRUE)
{
eprintf( "%s - Unable to compile vertex shader %d!\n", pchShaderName, nSceneVertexShader);
GLchar mess[3000];
GLsizei le;
glGetShaderInfoLog(nSceneVertexShader, 3000, &le, mess);
eprintf("error messages: %s", mess);
glDeleteProgram( unProgramID );
glDeleteShader( nSceneVertexShader );
return 0;
}
glAttachShader( unProgramID, nSceneVertexShader);
glDeleteShader( nSceneVertexShader ); // the program hangs onto this once it's attached
GLuint nSceneFragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource( nSceneFragmentShader, 1, &pchFragmentShader, nullptr);
glCompileShader( nSceneFragmentShader );
GLint fShaderCompiled = GL_FALSE;
glGetShaderiv( nSceneFragmentShader, GL_COMPILE_STATUS, &fShaderCompiled);
if (fShaderCompiled != GL_TRUE)
{
eprintf("%s - Unable to compile fragment shader %d!\n", pchShaderName, nSceneFragmentShader );
GLchar mess[3000];
GLsizei le;
glGetShaderInfoLog(nSceneFragmentShader, 3000, &le, mess);
eprintf("error messages: %s", mess);
glDeleteProgram( unProgramID );
glDeleteShader( nSceneFragmentShader );
return 0;
}
glAttachShader( unProgramID, nSceneFragmentShader );
glDeleteShader( nSceneFragmentShader ); // the program hangs onto this once it's attached
//tess
if (pchTessEvalShader) {
GLuint nSceneTessShader = glCreateShader(GL_TESS_EVALUATION_SHADER);
glShaderSource(nSceneTessShader, 1, &pchTessEvalShader, nullptr);
glCompileShader(nSceneTessShader);
GLint tShaderCompiled = GL_FALSE;
glGetShaderiv(nSceneTessShader, GL_COMPILE_STATUS, &tShaderCompiled);
if (tShaderCompiled != GL_TRUE)
{
eprintf("%s - Unable to compile tess eval shader %d!\n", pchShaderName, nSceneTessShader);
GLchar mess[3000];
GLsizei le;
glGetShaderInfoLog(nSceneTessShader, 3000, &le, mess);
eprintf("error messages: %s", mess);
glDeleteProgram(unProgramID);
glDeleteShader(nSceneTessShader);
return 0;
}
glAttachShader(unProgramID, nSceneTessShader);
glDeleteShader(nSceneTessShader); // the program hangs onto this once it's attached
}
glLinkProgram( unProgramID );
GLint programSuccess = GL_TRUE;
glGetProgramiv( unProgramID, GL_LINK_STATUS, &programSuccess);
if ( programSuccess != GL_TRUE )
{
eprintf("%s - Error linking program %d!\n", pchShaderName, unProgramID);
glDeleteProgram( unProgramID );
return 0;
}
glUseProgram( unProgramID );
glUseProgram( 0 );
return unProgramID;
}
#include "MyGL.h"
//-----------------------------------------------------------------------------
// Purpose: Compiles a GL shader program and returns the handle. Returns 0 if
// the shader couldn't be compiled for some reason.
//-----------------------------------------------------------------------------
GLuint CompileGLShader( const char *pchShaderName, const char *pchVertexShader, const char *pchFragmentShader,
const char *pchTessEvalShader = nullptr);
#include <algorithm>
#include "ConfigFile.h"
#include "atoms.hpp"
#include "eprintf.h"
const char * PATH;
const char * SCREENSHOT;
int ISOS;
int TIMESTEPS;
float **isocolours; // [ISOS][4];
const char **plyfiles;
float **translations;
float userpos[3];
float BACKGROUND[3];
int* numAtoms; //[timesteps]
float **atoms; //[timesteps][numAtoms[i]*4] //xyzu, u=atom number
float atomScaling;
std::vector<float> *clonedAtoms;
int numClonedAtoms;
int *basisvectorreps;
bool showTrajectories;
std::vector<int> atomtrajectories;
std::vector<std::vector<int>> atomtrajectoryrestarts;
float abc[3][3]; //basis vectors
bool has_abc = false;
int repetitions[3];
const char * loadConfigFileErrors[] =
{
"All Ok",//0
"file could not be opened", //-1
"unrecognized parameter",//-2
"values with no previous iso", //-3
"colours with no previous iso",//-4
"translations with no previous correct iso",//-5
"Missing isos and xyzfile",//-6
"missing values",//-7
"timesteps from config file and from atom file do not match",//-8, unused, now minimum is used
"isos parameter specified twice",//-9
"Error reading unit cell parameters", //-10
"Error reading repetitions",//-11
"Non-periodic, but repetitions requested", //-12
"No basis vectors, but repetitions requested", //-13
"Error loading config file",// -14
"Error loading xyz file, add 100 to see the error",//<-100
"Error loading cube file, add 100 to see the error",//<-200
"Error loading json file, add 200 to see the error",//<-300
};
void updateTIMESTEPS (int timesteps)
{
if (TIMESTEPS==0)
TIMESTEPS=timesteps;
else
TIMESTEPS=std::min(TIMESTEPS, timesteps);
}
int readString(FILE *f, char *s)
{
char s2[100];
int r, c;
r = fscanf(f, "%99s", s2);
if (r!=1)
return -1;
if (s2[0]!='"') {
strcpy(s, s2);
return 0;
} else {
strcpy(s, s2+1); //skip "
size_t l = strlen(s);
if (s[l-1] == '"') {
s[l-1] = '\0';
return 0;
}
else {
char *p = s2;
do {
c = fgetc(f);
*p++ = c;
} while (c != EOF && c != '"');
*(p-1) = '\0';
strcat(s, s2);
}
}
return 0;
}
void fixFile(char * file)
{
#ifdef WIN32
const char c='\\';
#else
const char c='/';
#endif
while (*file!='\0') {
if (*file=='/' || *file=='\\')
*file=c;
file++;
}
}
int loadConfigFile(const char * f)
{
//default values
eprintf ("load config file start");
bool nonperiodic=false;
char base_url[1024]="http://enc-testing-nomad.esc.rzg.mpg.de/v1.0/materials/";
char material[1024]="";
BACKGROUND[0] = 0.95f;
BACKGROUND[1] = 0.95f;
BACKGROUND[2] = 0.95f;
SCREENSHOT="C:\\temp\\frame";
ISOS = 0;
TIMESTEPS=0;
PATH=strdup("");
numAtoms=0;
atomScaling=1;
clonedAtoms=0;
showTrajectories = false;
basisvectorreps=0;
numClonedAtoms=0;
for (int i=0;i<3;i++)
repetitions[i]=1;
for (int i=0;i<3;i++)
userpos[i] = 0;
//
FILE *F = fopen(f, "r");
if (F == 0)
{
eprintf( "Could not open config file %s\n", f);
return -1;
}
char s[100];
int r;
while (!feof(F)) {
r=fscanf(F, "%99s", s);
if (r <= 0)
continue;
if (s[0] == '#') {//comment
discardline(F);
continue;
}
if (!strcmp(s, "timesteps")) {
int timesteps;
r = fscanf(F, "%d", &timesteps);
if (TIMESTEPS==0)
TIMESTEPS=timesteps;
else
TIMESTEPS=std::min(TIMESTEPS, timesteps);
}
else if (!strcmp(s, "isos")) {
if (ISOS!=0)
return -9;
r = fscanf(F, "%d", &ISOS);
plyfiles = new const char*[ISOS];
isocolours = new float*[ISOS];
translations = new float*[ISOS];
for (int i = 0; i < ISOS; i++) {
plyfiles[i] = strdup("");
isocolours[i] = new float[4];
translations[i] = new float[3];
//default values
for (int j = 0; j < 4; j++)
isocolours[i][j] = 1.f;
for (int j = 0; j < 3; j++)
translations[i][j] = 0.f;
}
}
else if (!strcmp(s, "values")) {
if (ISOS == 0) {
eprintf( "values with no previous correct isos parameter\n");
fclose(F);
return -3;
}
for (int i = 0; i < ISOS; i++) {
r=readString(F, s);
if (r!=0)
return -14;
free ((void*)(plyfiles[i]));
plyfiles[i] = strdup(s);
}
}
else if (!strcmp(s, "colours")) {
if (ISOS == 0) {
eprintf( "colours with no previous correct isos parameter\n");
return -4;
}
for (int i = 0; i < ISOS; i++) {
for (int j = 0; j < 4; j++)
r = fscanf(F, "%f", &(isocolours[i][j]));
//if (r==0)
}
}
else if (!strcmp(s, "path")) {
r=readString(F, s);
if (r!=0)
return -14;
free((void*)PATH);
PATH = strdup(s);
}
else if (!strcmp(s, "background")) {
for (int i = 0; i < 3; i++)
r = fscanf(F, "%f", BACKGROUND + i);
}
else if (!strcmp(s, "translations")) {
if (ISOS == 0) {
eprintf( "translations with no previous correct isos parameter\n");
fclose(F);
return -5;
}
for (int i=0;i<ISOS;i++)
for (int j = 0; j < 3; j++) {
r = fscanf(F, "%f", &(translations[i][j]));
}
}
else if (!strcmp(s, "userpos")) {
for (int j = 0; j < 3; j++) {
r = fscanf(F, "%f", &(userpos[j]));
}
}
else if (!strcmp(s, "screenshot")) {
r=readString(F, s);
if (r!=0)
return -14;
SCREENSHOT = strdup(s);
}
else if (!strcmp(s, "xyzfile")||!strcmp(s, "atomfile")) {
r=readString(F, s);
if (r!=0)
return -14;
int timesteps;
char file[256];
sprintf (file, "%s%s", PATH, s);
fixFile(file);
int e;
e=readAtomsXYZ(file, &numAtoms, &timesteps, &atoms);
if (e<0)
return e-100;
updateTIMESTEPS (timesteps);
}
else if (!strcmp(s, "cubefile")) {
r=readString(F, s);
if (r!=0)
return -14;
int timesteps;
char file[256];
sprintf(file, "%s%s", PATH, s);
fixFile(file);
int e;
e = readAtomsCube(file, &numAtoms, &timesteps, &atoms);
if (e<0)
return e - 200;
updateTIMESTEPS (timesteps);
// return -8;
}
else if (!strcmp(s, "atomscaling")) {
r = fscanf(F, "%f", &atomScaling);
}
else if (!strcmp(s, "abc")) {
for (int i=0;i<3;i++)
for (int j=0;j<3;j++) {
r = fscanf(F, "%f", &(abc[i][j]));
if (r!=1)
return -10;
}
has_abc = true;
}
else if (!strcmp(s, "json")) {
r=readString(F, s);
if (r!=0)
return -14;
char file[256];
sprintf(file, "%s%s", PATH, s);
fixFile(file);
int e;
int timesteps;
//rgh fixme, we know only one
e = readAtomsJson (file, &numAtoms, &timesteps, &atoms, abc, &clonedAtoms);
if (e<0)
return e-300;
numClonedAtoms=clonedAtoms[0].size()/4;
has_abc=true;
updateTIMESTEPS (timesteps);
}
else if (!strcmp(s, "baseurl")) {
r=readString (F, base_url);
if (r!=0)
return -14;
}
else if (!strcmp(s, "jsonurl")) {
int e;
int timesteps;
r=readString (F, material);
if (r!=0)
return -14;
char url[2048];
sprintf (url, "%s%s", base_url, material);
//rgh fixme, we know only one
eprintf ("load config file start, before readAtomsJsonURL");
e = readAtomsJsonURL (url, &numAtoms, &timesteps, &atoms, abc, &clonedAtoms);
eprintf ("load config file start, after readAtomsJsonURL");
if (e<0)
return e-300;
numClonedAtoms=clonedAtoms[0].size()/4;
has_abc=true;
updateTIMESTEPS (timesteps);
}
else if (!strcmp(s, "showtrajectory")) {
showTrajectories = true;
int atom;
while (1 == (r = fscanf(F, "%d", &atom))) {
atomtrajectories.push_back(atom - 1);
}
if (atomtrajectories.size() == 0) //empty showtrajectory
showTrajectories = false;
} else if (!strcmp(s, "nonperiodic")) {
nonperiodic=true;
} else if (!strcmp(s, "repetitions")) {
for (int j=0;j<3;j++) {
r = fscanf(F, "%d", repetitions+j);
if (r!=1)
return -11;
}
}
else {
eprintf( "Unrecognized parameter %s\n", s);
fclose(F);
return -2;
}
}
//verification and additional processing
fclose(F);
if (ISOS == 0 && numAtoms==0) {
eprintf( "Missing isos and atomfile parameter\n");
return -6;
}
if (ISOS !=0 && plyfiles[0] == 0) {
eprintf( "Missing values parameter\n");
fclose(F);
return -7;
}
if (nonperiodic) {
numClonedAtoms=0;
if (repetitions[0]!=1 ||repetitions[1]!=1 ||repetitions[2]!=1)
return -12;
}
if (repetitions[0]!=1 ||repetitions[1]!=1 ||repetitions[2]!=1) {
if (!has_abc)
return (-13);
numClonedAtoms=0;
}
if (showTrajectories && atomtrajectories[0]<0) {
atomtrajectories.clear();
for (int i=0;i<*numAtoms;i++)
atomtrajectories.push_back(i);
}
return 0;
}
\ No newline at end of file
#ifndef __CONFIGFILE_H
#define __CONFIGFILE_H
#include <vector>
extern const char * PATH;
extern const char * SCREENSHOT;
extern int ISOS;
extern int TIMESTEPS;
extern float **isocolours; // [ISOS][4];
extern const char **plyfiles;
extern float **translations;
extern float userpos[3];
extern float BACKGROUND[3];
extern int* numAtoms; //[timesteps]
extern float **atoms; //[timesteps][numAtoms[i]*4] //xyzu, u=atom number
extern float atomScaling;
extern std::vector<float> *clonedAtoms;
extern int numClonedAtoms;
extern int *basisvectorreps;
extern bool showTrajectories;
extern std::vector<int> atomtrajectories;
extern std::vector<std::vector<int>> atomtrajectoryrestarts;
extern float abc[3][3]; //basis vectors
extern bool has_abc;
extern int repetitions[3];
extern const char * loadConfigFileErrors[];
int loadConfigFile(const char * f);
#endif //__CONFIGFILE_H
#ifndef __MYGL_H
#define __MYGL_H
//FIXME, support more platforms in the future
#ifdef WIN32
#include <GL/glew.h>
#else // Samsung GearVR + Oculus Mobile
#include "Kernel/OVR_GlUtils.h"
#include "GLES2/gl2ext.h"
//ndk r10e does not provide opengles 3.2
#ifndef GL_TESS_EVALUATION_SHADER
#define GL_TESS_EVALUATION_SHADER GL_TESS_EVALUATION_SHADER_EXT
#endif
#endif
#endif //__MYGL_H
\ No newline at end of file
#include "TessShaders.h"
/*rgh: for now default tesselation control, using
glPatchParameterfv(GL_PATCH_DEFAULT_OUTER_LEVEL, {3,3,3,3});
glPatchParameterfv(GL_PATCH_DEFAULT_INNER_LEVEL, {3,3});
*/
const char * const AtomShaders [] = {
"Atom Renderer",
// vertex shader
//Android 21 gives error: only supports up to '310 es'
#ifdef WIN32
"#version 410\n"
#else
"#version 310 es\n"
#endif
"uniform sampler2D atomData;\n"
"layout(location = 0) in vec3 center;\n"
"layout(location = 1) in float atomIn;\n"
"out vec4 vcolor;\n" //color , radius
"out vec3 vcen;"
"void main()\n"
"{\n"
//"gl_Position = matrix * vec4(position+center, 1);\n"
"float coord=atomIn/118.0+0.5/118.0;\n"
"vcolor=vec4(texture(atomData, vec2(coord, 0)));\n"
"vcen=center;\n"
//"color.a=1;\n"
"}\n",
//fragment shader
#ifdef WIN32
"#version 410 core\n"
#else
"#version 310 es\n"
#endif
"in lowp vec4 color;\n"
// "in highp vec3 vertex;"
"in highp vec3 normal;"
"out lowp vec4 outputColor;\n"
"void main()\n"
"{\n"
//"vec3 U = dFdx(vertex); "
//"vec3 V = dFdy(vertex); "
"highp vec3 nn = normalize(normal);"
//"vec3 nn = normalize(cross(U,V));"
"lowp float a=abs(dot(nn, vec3(0,sqrt(2.0)/2.0,sqrt(2.0)/2.0)));\n"
"lowp float b=max(0.0, dot(nn, vec3(0,0,1)));\n"
"highp vec4 res=color;\n"
" outputColor = vec4 ((res.rgb) * (0.1 + 0.2*a), color.a);\n"
"}\n",
//tess eval
#ifdef WIN32
"#version 400\n"
#else
"#version 320 es\n"
#endif
//"layout(triangles, equal_spacing, cw) in;\n"
"layout(quads, equal_spacing, cw) in;\n"
"#define pi 3.1415926535897932384626433832795\n"
"uniform mat4 matrix;\n"
//"uniform mat4 mv;\n"
"in vec4 vcolor[];\n" //color , radius
"in vec3 vcen[];"
"out vec4 color;\n" //color
"out vec3 normal;\n"
// "out vec3 vertex;"
"uniform mat4 Projection;\n"
"uniform mat4 Modelview;\n"