From 85c755ae0c58df0b37a7e32aa43f9c75ee0100a7 Mon Sep 17 00:00:00 2001 From: "Garcia-Hernandez, Ruben Jesus (rgarcia)" <garcia@lrz.de> Date: Wed, 12 Jul 2017 15:16:18 +0200 Subject: [PATCH] bond calculation fix stereo screenshot option (vive) configurable atom colours downsampling of screenshots option --- NOMADVRLib/ConfigFile.cpp | 29 +++++++++ NOMADVRLib/ConfigFile.h | 3 + NOMADVRLib/atoms.cpp | 4 ++ NOMADVRLib/atoms.hpp | 1 + NOMADVRLib/atomsGL.cpp | 5 +- OpenVR/TimestepData/hellovr_opengl_main.cpp | 72 +++++++++++++++++---- 6 files changed, 99 insertions(+), 15 deletions(-) diff --git a/NOMADVRLib/ConfigFile.cpp b/NOMADVRLib/ConfigFile.cpp index 612f9f5..10ff95a 100644 --- a/NOMADVRLib/ConfigFile.cpp +++ b/NOMADVRLib/ConfigFile.cpp @@ -44,10 +44,15 @@ int voxelSize[3]; int repetitions[3]; Solid *solid; +bool saveStereo; +int screenshotdownscaling; + //markers such as hole positions and electron positions float ** markers; float ** markercolours; float cubetrans[3]; + + const char * loadConfigFileErrors[] = { "All Ok",//0 @@ -69,6 +74,7 @@ const char * loadConfigFileErrors[] = "Error reading token", //-16 "markers with no previous correct timesteps parameter", //-17 "markercolours with no previous correct timesteps parameter", //-18 + "Error reading atomcolour", // -19 "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 @@ -168,6 +174,8 @@ int loadConfigFile(const char * f) translations=nullptr; for (int i=0;i<3;i++) voxelSize[i]=-1; + saveStereo=false; + screenshotdownscaling=1; // FILE *F = fopen(f, "r"); if (F == 0) @@ -439,10 +447,31 @@ int loadConfigFile(const char * f) } } else if (!strcmp (s, "displaybonds")) { displaybonds=true; + } else if (!strcmp (s, "atomcolour")) { + char atom [100]; + float rgb[3]; + r = fscanf(F, "%s %f", atom, rgb, rgb + 1, rgb + 2); + if (r!=4) { + eprintf ("Error loading atom colour"); + return -19; + } + int a=findAtom(atom); + if (a==-1) { + eprintf ("atomcolour, unknown atom type %s", atom); + return -19; + } + for (int i=0;i<3;i++) + atomColours[a][i]=rgb[i]; } else if (!strcmp (s, "markerscaling")) { r = fscanf(F, "%f", &markerscaling); } else if (!strcmp (s, "displayunitcell")) { displayunitcell=true; + } else if (!strcmp (s, "stereoscreenshot")) { + saveStereo=true; + } else if (!strcmp (s, "screenshotdownscaling")) { + r= fscanf(F, "%d", &screenshotdownscaling); + if (r<1) + eprintf ("Error reading screenshotdownscaling value"); } else if (!strcmp (s, "supercell")) { r=fscanf (F, "%f %f %f", supercell, supercell+1, supercell+2); } else if (!strcmp (s, "\x0d")) { //discard windows newline (problem in Sebastian Kokott's phone (?!) diff --git a/NOMADVRLib/ConfigFile.h b/NOMADVRLib/ConfigFile.h index 84c5827..690d90a 100644 --- a/NOMADVRLib/ConfigFile.h +++ b/NOMADVRLib/ConfigFile.h @@ -39,6 +39,9 @@ extern int repetitions[3]; extern Solid *solid; +extern bool saveStereo; +extern int screenshotdownscaling; + //markers such as hole positions and electron positions extern float ** markers; extern float ** markercolours; diff --git a/NOMADVRLib/atoms.cpp b/NOMADVRLib/atoms.cpp index 1496bc2..8a8f1b6 100644 --- a/NOMADVRLib/atoms.cpp +++ b/NOMADVRLib/atoms.cpp @@ -73,7 +73,11 @@ float atomColours[][4] = {0.941000f, 0.565000f, 0.627000f, 1.260000f},//Co {0.314000f, 0.816000f, 0.314000f, 1.240000f},//Ni {0.784000f, 0.502000f, 0.200000f, 1.320000f},//Cu +// This is the standard colour {0.490000f, 0.502000f, 0.690000f, 1.220000f},//Zn +// This is Andris's colour +//{0.625f,0.125f,0.9375f, 1.220000f},//Zn + {0.761000f, 0.561000f, 0.561000f, 1.220000f},//Ga {0.400000f, 0.561000f, 0.561000f, 1.200000f},//Ge {0.741000f, 0.502000f, 0.890000f, 1.190000f},//As diff --git a/NOMADVRLib/atoms.hpp b/NOMADVRLib/atoms.hpp index ea634c0..7c6a743 100644 --- a/NOMADVRLib/atoms.hpp +++ b/NOMADVRLib/atoms.hpp @@ -30,6 +30,7 @@ extern const char * readAtomsCubeErrors[]; extern const char * readAtomsJsonErrors[]; float atomRadius (int i); +int findAtom(const char *const s); //internal functions void discardline (FILE *F); diff --git a/NOMADVRLib/atomsGL.cpp b/NOMADVRLib/atomsGL.cpp index 82d1fb6..a238715 100644 --- a/NOMADVRLib/atomsGL.cpp +++ b/NOMADVRLib/atomsGL.cpp @@ -256,6 +256,7 @@ GLenum SetupAtoms(GLuint **AtomVAO /*[3]*/, GLuint **AtomVertBuffer /*[2]*/, GLu float *current=tmp; const int atomlimit=30; + const float bondscaling=0.7f; numBonds=new int[getAtomTimesteps() ]; for (int p=0;p<getAtomTimesteps() ;p++) { @@ -278,7 +279,7 @@ GLenum SetupAtoms(GLuint **AtomVAO /*[3]*/, GLuint **AtomVertBuffer /*[2]*/, GLu } r=atomRadius(static_cast<int>(atoms[p][4 * a1 + 3]))+ atomRadius(static_cast<int>(atoms[p][4 * a2 + 3])); - if (d*0.9f<r*r) {// bond + if (d*bondscaling<r*r) {// bond bonds.push_back(a1+(p==0?0:numAtoms[p-1])); bonds.push_back(a2+(p==0?0:numAtoms[p-1])); } @@ -300,7 +301,7 @@ GLenum SetupAtoms(GLuint **AtomVAO /*[3]*/, GLuint **AtomVertBuffer /*[2]*/, GLu M[k]=atoms[p][4*a+k]; } } - grid g(m, M, pow(numAtoms[p], 1.0/3), 0.9f); + grid g(m, M, pow(numAtoms[p], 1.0/3), bondscaling); for (int a = 1; a < numAtoms[p]; a++) g.add(atoms[p]+4*a); for (int a = 0; a < numAtoms[p]; a++) { diff --git a/OpenVR/TimestepData/hellovr_opengl_main.cpp b/OpenVR/TimestepData/hellovr_opengl_main.cpp index 18cc781..19450c8 100644 --- a/OpenVR/TimestepData/hellovr_opengl_main.cpp +++ b/OpenVR/TimestepData/hellovr_opengl_main.cpp @@ -191,6 +191,8 @@ private: // OpenGL bookkeeping int m_iValidPoseCount_Last; bool m_bShowCubes; bool buttonPressed[2][vr::k_unMaxTrackedDeviceCount]; //grip, application menu + bool AtomsButtonPressed[2]; + bool showAtoms; std::string m_strPoseClasses; // what classes we saw poses for this frame char m_rDevClassChar[vr::k_unMaxTrackedDeviceCount]; // for each device, a character representing its class @@ -205,6 +207,8 @@ private: // OpenGL bookkeeping float m_fNearClip; float m_fFarClip; + void SaveScreenshot (char *name); + GLuint *m_iTexture; //[3+ZLAYERS+1] // white, depth1, depth2, color[ZLAYERS], atomtexture SDL_Texture **axisTextures; //[6] GLuint peelingFramebuffer; @@ -303,7 +307,7 @@ private: // OpenGL bookkeeping std::vector< CGLRenderModel * > m_vecRenderModels; CGLRenderModel *m_rTrackedDeviceToRenderModel[ vr::k_unMaxTrackedDeviceCount ]; - char * pixels; //for saving screenshots to disk + char *pixels, *pixels2; //for saving screenshots to disk int framecounter; bool savetodisk; }; @@ -423,7 +427,7 @@ CMainApplication::CMainApplication(int argc, char *argv[]) for (int i = 0; i < vr::k_unMaxTrackedDeviceCount; i++) { buttonPressed[j][i] = false; } - + showAtoms=true; for( int i = 1; i < argc; i++ ) { if( !stricmp( argv[i], "-gldebug" ) ) @@ -939,19 +943,26 @@ bool CMainApplication::HandleInput() vr::VRControllerState_t state; if (m_pHMD->GetControllerState(unDevice, &state)) { - m_rbShowTrackedDevice[unDevice] = state.ulButtonPressed == 0; + //this hides the controllers when buttons are pressed. Why?! -> + //rgh: the name of the variable seems to make it so :o) Possibly so that a different model can be used with the correct deformation + //m_rbShowTrackedDevice[unDevice] = state.ulButtonPressed == 0; if (!buttonPressed[1][unDevice] && state.ulButtonTouched&vr::ButtonMaskFromId(vr::k_EButton_ApplicationMenu)) { buttonPressed[1][unDevice] = true; if (firstdevice == -1) firstdevice = unDevice; - savetodisk = !savetodisk; + + if (firstdevice==unDevice) + savetodisk = !savetodisk; + else + showAtoms= !showAtoms; } else if (buttonPressed[1][unDevice] && 0 == (state.ulButtonTouched&vr::ButtonMaskFromId(vr::k_EButton_ApplicationMenu))) { buttonPressed[1][unDevice] = false; } + if (!buttonPressed[0][unDevice] && state.ulButtonTouched&vr::ButtonMaskFromId(vr::k_EButton_Grip)) { buttonPressed[0][unDevice] = true; @@ -1761,7 +1772,12 @@ bool CMainApplication::SetupStereoRenderTargets() CreateFrameBuffer( m_nRenderWidth, m_nRenderHeight, rightEyeDesc ); pixels = new char [m_nRenderWidth*m_nRenderHeight*3]; - + if (m_nRenderHeight%screenshotdownscaling!=0) + dprintf("Height not multiple of screenshot scale"); + if (m_nRenderWidth%screenshotdownscaling!=0) + dprintf("Width not multiple of screenshot scale"); + if (screenshotdownscaling!=1) + pixels2= new char[m_nRenderWidth*m_nRenderHeight*3/screenshotdownscaling/screenshotdownscaling]; return true; } @@ -1902,6 +1918,34 @@ void CMainApplication::SetupDistortion() } +void CMainApplication::SaveScreenshot (char *name) +{ +SDL_Surface *s; +int x=m_nRenderWidth/screenshotdownscaling; +int y=m_nRenderHeight/screenshotdownscaling; +glPixelStorei(GL_PACK_ALIGNMENT, 1); +glReadPixels(0, 0, m_nRenderWidth, m_nRenderHeight, GL_RGB, GL_UNSIGNED_BYTE, pixels); + + //little endian machine, R and B are flipped + if (screenshotdownscaling==1) { + s = SDL_CreateRGBSurfaceFrom(pixels, x, y, 24, 3 * y, 0xff, 0xff00, 0xff0000, 0); + } else { + for (int i=0;i<x;i++) + for (int j=0;j<y;j++) { + short rgb[3]={0,0,0}; + for (int k=0;k<screenshotdownscaling;k++) //horiz + for (int l=0;l<screenshotdownscaling;l++) //vert + for (int m=0;m<3;m++) + rgb[m]+=pixels[j*3*m_nRenderWidth*screenshotdownscaling+i*3*screenshotdownscaling +l*3*m_nRenderWidth+k*3 +m]; + for (int m=0;m<3;m++) + pixels2[i*3+j*3*m_nRenderWidth/screenshotdownscaling+m]=rgb[m]/screenshotdownscaling/screenshotdownscaling; + } + s = SDL_CreateRGBSurfaceFrom(pixels2, x, y, 24, 3 * y, 0xff, 0xff00, 0xff0000, 0); + } + SDL_SaveBMP(s, name); + +} + //----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- @@ -1921,11 +1965,7 @@ void CMainApplication::RenderStereoTargets() if (savetodisk) { sprintf(name, "%sL%05d.bmp", SCREENSHOT, framecounter); - glPixelStorei(GL_PACK_ALIGNMENT, 1); - glReadPixels(0, 0, m_nRenderWidth, m_nRenderHeight, GL_RGB, GL_UNSIGNED_BYTE, pixels); - //little endian machine, R and B are flipped - SDL_Surface *s = SDL_CreateRGBSurfaceFrom(pixels, m_nRenderWidth, m_nRenderHeight, 24, 3 * m_nRenderWidth, 0xff, 0xff00, 0xff0000, 0); - SDL_SaveBMP(s, name); + SaveScreenshot(name); } glBindFramebuffer( GL_FRAMEBUFFER, 0 ); @@ -1948,6 +1988,12 @@ void CMainApplication::RenderStereoTargets() glBindFramebuffer( GL_FRAMEBUFFER, rightEyeDesc.m_nRenderFramebufferId ); glViewport(0, 0, m_nRenderWidth, m_nRenderHeight ); RenderScene( vr::Eye_Right ); + + if (savetodisk && saveStereo) { + sprintf(name, "%sR%05d.bmp", SCREENSHOT, framecounter); + SaveScreenshot(name); + } + glBindFramebuffer( GL_FRAMEBUFFER, 0 ); glDisable( GL_MULTISAMPLE ); @@ -2073,7 +2119,7 @@ glPatchParameteri(GL_PATCH_VERTICES, 1); trans.translate(iPos).rotateX(-90).translate(UserPosition); Matrix4 transform = GetCurrentViewProjectionMatrix(nEye)*trans; -if (numAtoms) { +if (numAtoms && showAtoms) { glBindVertexArray(m_unAtomVAO[0]); glEnableVertexAttribArray(0); glEnableVertexAttribArray(1); @@ -2095,7 +2141,7 @@ if (numAtoms) { dprintf("Gl error after RenderAtoms timestep =%d: %d, %s\n", currentset, e, gluErrorString(e)); } //now cloned atoms -if (numClonedAtoms!=0 && (currentset==0||fixedAtoms)) { +if (numClonedAtoms!=0 && (currentset==0||fixedAtoms) && showAtoms) { glBindVertexArray(m_unAtomVAO[1]); glDrawArrays(GL_PATCHES, 0, numClonedAtoms); if ((e = glGetError()) != GL_NO_ERROR) @@ -2103,7 +2149,7 @@ if (numClonedAtoms!=0 && (currentset==0||fixedAtoms)) { } //now bonds -if (numBonds && displaybonds) { +if (numBonds && displaybonds && showAtoms) { glBindVertexArray(m_unAtomVAO[2]); glUseProgram(m_unUnitCellProgramID); glUniformMatrix4fv(m_nUnitCellMatrixLocation, 1, GL_FALSE, transform.get()); -- GitLab