Start work on client/server.

Vive: Display iso and timestep, fix cleanup
parent 1feeb8ca
......@@ -82,6 +82,10 @@ menubutton_t menubutton;
std::vector<information> info;
int secret;
const char * server;
int port;
const char * loadConfigFileErrors[] =
{
"All Ok",//0
......@@ -290,6 +294,10 @@ void initState()
bondscaling = 0.7f;
bondThickness = 1.0f;
secret=0;
server=nullptr;
port=-1;
}
int loadConfigFile(const char * f)
......@@ -530,7 +538,7 @@ int loadConfigFile(const char * f)
return -11;
}
} else if (!strcmp(s, "atomglyph")) {
r=fscanf (F, "%s", s);
r=fscanf (F, "%99s", s);
if (r==0)
return -15;
if (!strcmp(s, "icosahedron"))
......@@ -606,7 +614,7 @@ int loadConfigFile(const char * f)
} else if (!strcmp (s, "atomcolour")) {
char atom [100];
float rgb[3];
r = fscanf(F, "%s %f %f %f", atom, rgb, rgb + 1, rgb + 2);
r = fscanf(F, "%99s %f %f %f", atom, rgb, rgb + 1, rgb + 2);
if (r!=4) {
eprintf ("Error loading atom colour");
return -19;
......@@ -622,7 +630,7 @@ int loadConfigFile(const char * f)
char atom [100];
float rgb[3];
float size;
r = fscanf(F, "%s %f %f %f %f", atom, rgb, rgb + 1, rgb + 2, &size);
r = fscanf(F, "%99s %f %f %f %f", atom, rgb, rgb + 1, rgb + 2, &size);
if (r!=5) {
eprintf ("Error loading newatom");
return -20;
......@@ -711,7 +719,7 @@ int loadConfigFile(const char * f)
eprintf("Error reading bondthickness");
}
else if (!strcmp(s, "menubutton")) {
r = fscanf(F, "%s", s);
r = fscanf(F, "%99s", s);
if (!strcmp(s, "Record"))
menubutton = Record;
else if (!strcmp(s, "Infobox"))
......@@ -743,6 +751,15 @@ int loadConfigFile(const char * f)
#endif
} else if (!strcmp (s, "\x0d")) { //discard windows newline (problem in Sebastian Kokott's phone (?!)
continue;
} else if (!strcmp (s, "server")) { //multiuser support
int r;
if (server)
delete(server);
server=new char[100];
r=fscanf (F, "%99s %d %d", server, &port, &secret);
if (r<3) {
eprintf ("Error reading server paramters");
}
} else {
eprintf( "Unrecognized parameter %s\n", s);
for (int i=0;i<strlen(s);i++)
......
......@@ -83,6 +83,11 @@ extern const char * loadConfigFileErrors[];
void cleanConfig();
int loadConfigFile(const char * f);
//for multiuser
extern int secret;
extern const char * server;
extern int port;
struct information {
float pos[3];
float size;
......
......@@ -674,6 +674,8 @@ GLenum SetupMarker(GLuint *MarkerVAO, GLuint *MarkerVertBuffer)
void CleanUnitCell (GLuint *UnitCellVAO, GLuint *UnitCellVertBuffer, GLuint *UnitCellIndexBuffer)
{
if (!has_abc)
return;
glDeleteVertexArrays(1, UnitCellVAO);
glDeleteBuffers(1, UnitCellVertBuffer);
glDeleteBuffers(1, UnitCellIndexBuffer);
......
/*
# Copyright 2016-2018 Ruben Jesus Garcia Hernandez
# Copyright 2016-2018 Ruben Jesus Garcia-Hernandez
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
......@@ -16,18 +16,23 @@
#include <vector>
#include "LoadPNG.h"
#include "NOMADVRLib/eprintf.h"
#include "shared/lodepng.h"
GLuint LoadPNG (const char *image)
GLuint LoadPNG(const char *image, int renderMode)
{
GLuint m_iTexture;
glGenTextures(1, &m_iTexture);
glBindTexture(GL_TEXTURE_2D, m_iTexture);
std::vector<unsigned char> imageRGBA;
unsigned nImageWidth, nImageHeight;
unsigned nError = lodepng::decode(imageRGBA, nImageWidth, nImageHeight,
image);
if (nError!=0) {
eprintf ("Error loading texture %s, lodepng::decode error %d", image, nError);
return 0;
}
GLuint m_iTexture;
glGenTextures(1, &m_iTexture);
glBindTexture(GL_TEXTURE_2D, m_iTexture);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, nImageWidth, nImageHeight,
0, GL_RGBA, GL_UNSIGNED_BYTE, &imageRGBA[0]);
......@@ -36,9 +41,19 @@ GLuint LoadPNG (const char *image)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
switch (renderMode) {
case linear:
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
break;
case nearest:
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
break;
default:
eprintf("Error, unknown render mode in LoadPNG");
return 0;
}
//rgh fixme: revise this if texture sampling is too slow
GLfloat fLargest;
glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &fLargest);
......
/*
# Copyright 2016-2018 Ruben Jesus Garcia Hernandez
# Copyright 2016-2018 Ruben Jesus Garcia-Hernandez
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
......@@ -18,6 +18,12 @@
#define LOADPNG_H
#include "NOMADVRLib/MyGL.h"
GLuint LoadPNG (const char *image);
enum RenderMode {
linear = 0,
nearest = 1,
error = 2
};
GLuint LoadPNG(const char *image, int renderMode=linear);
#endif
......@@ -32,6 +32,7 @@
#define new DEBUG_NEW
#include <vector>
#include <thread>
#include <SDL.h>
#include <GL/glew.h>
......@@ -348,6 +349,10 @@ private: // OpenGL bookkeeping
int myargc;
char **myargv;
int currentConfig;
std::thread *tcpconn;
void connectTCP();
int sock;
};
const float CMainApplication::videospeed = 0.01f;
......@@ -429,9 +434,85 @@ int CMainApplication::LoadConfigFile (const char *c)
if (solid)
MessageBoxA(0, "Only spheres implemented as atom glyphs in HTC Vive", "Atom Glyph", 0);
//change currentiso if needed
if (currentiso > ISOS || currentiso <0)
currentiso = (currentiso + ISOS + 1) % (ISOS+1); //beware of (-1)
//add multiuser support
if (port!=-1 && tcpconn==nullptr) { //do not change servers as we change config file for now
tcpconn=new std::thread(&CMainApplication::connectTCP, this);
}
return r;
}
void CMainApplication::connectTCP()
{
//https://stackoverflow.com/questions/5444197/converting-host-to-ip-by-sockaddr-in-gethostname-etc
struct sockaddr_in serv_addr;
struct hostent *he;
if ( (he = gethostbyname(server) ) == nullptr ) {
return; /* error */
}
memset((char *) &serv_addr, 0, sizeof(serv_addr));
memcpy(&serv_addr.sin_addr, he->h_addr_list[0], he->h_length);
serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons(port);
sock=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
if ( connect(sock, (struct sockaddr *)&serv_addr, sizeof(serv_addr))) {
return; /* error */
}
//read state
int n;
int32_t tmp;
tmp=htonl (secret);
n = send(sock, (char*)&tmp , sizeof(tmp), 0);
if (n<sizeof(tmp))
return;
char what;
while (true) {
n=recv(sock, &what, sizeof(what), 0);
if (n<1)
return;
switch (what) {
case 't':
n=recv (sock, (char*)&tmp, sizeof(tmp), 0);
if (n<sizeof(tmp))
return;
currentset=ntohl(tmp)%TIMESTEPS;
break;
case 'i':
n=recv (sock, (char*)&tmp, sizeof(tmp), 0);
if (n<sizeof(tmp))
return;
currentiso=ntohl(tmp)%(ISOS+1);
break;
case 's':
char s;
n=recv (sock, &s, sizeof(s), 0);
if (n<sizeof(s))
return;
showAtoms=(bool)s;
break;
case 'n':
n=recv (sock, (char*)&tmp, sizeof(tmp), 0);
if (n<sizeof(tmp))
return;
//load config file
if (currentConfig!=ntohl(tmp)%myargc) {
currentConfig=ntohl(tmp)%myargc;
CleanScene();
LoadConfigFile(myargv[currentConfig]);
SetupScene();
}
break;
default:
eprintf ("Unknown state sent from server: %c\n", what);
}
}
}
//-----------------------------------------------------------------------------
// Purpose: Constructor
//-----------------------------------------------------------------------------
......@@ -480,7 +561,7 @@ CMainApplication::CMainApplication(int argc, char *argv[])
, m_bShowCubes(true)
, currentset(0)
, elapsedtime(videospeed*float(SDL_GetTicks()))
, currentiso(ISOS)
, currentiso(-1) // (-> ISOS, but at this point ISOS is not yet initialized)
, firstdevice(-1)
, seconddevice(-1)
, m_iTexture(0)
......@@ -500,6 +581,8 @@ CMainApplication::CMainApplication(int argc, char *argv[])
, myargc(argc)
, myargv(argv)
, currentConfig(1)
, tcpconn(0)
, sock(-1)
{
LoadConfigFile(argv[currentConfig]);
for (int j=0;j<3;j++)
......@@ -1006,6 +1089,22 @@ bool CMainApplication::HandleInput()
currentConfig++;
if (currentConfig>=myargc)
currentConfig=1;
if (sock>=0) {
char w='c';
int32_t tmp;
tmp=htonl(currentConfig);
int n;
n=send(sock, &w, sizeof(w), 0);
if (n<sizeof(w)) {
closesocket(sock);
sock=-1;
}
n=send(sock, (char*)&tmp, sizeof(tmp), 0);
if (n<sizeof(tmp)) {
closesocket(sock);
sock=-1;
}
}
CleanScene();
LoadConfigFile(myargv[currentConfig]);
SetupScene();
......@@ -1492,6 +1591,8 @@ bool CMainApplication::SetupTexturemaps()
else
path=s.substr(0, l)+"\\"+NUMBERTEXTURE;
numbersTexture=LoadPNG(path.c_str(), nearest);
if (numbersTexture==0)
eprintf ("Error loading %s\n", path);
return ( m_iTexture != 0 && e==GL_NO_ERROR);
}
......@@ -1535,8 +1636,10 @@ void CMainApplication::CleanScene()
ISOS=0;
}
//atoms
if (atoms) {
::CleanAtoms(&m_unAtomVAO, &m_glAtomVertBuffer, &BondIndices);
::cleanAtoms(&numAtoms, TIMESTEPS, &atoms);
}
//unit cell
::CleanUnitCell(&m_unUnitCellVAO, &m_glUnitCellVertBuffer, &m_glUnitCellIndexBuffer);
//marker
......@@ -1739,49 +1842,39 @@ float GetTextureCoordinate (char c)
return u;
}
//if selected atom, display atom # and distance.
//Otherwise, display timestep in firstdevice and iso in seconddevice
void CMainApplication::RenderControllerGlyph (const vr::Hmd_Eye nEye, const int controller)
{
if (selectedAtom==-1)
return;
if (controller == seconddevice) {
char string[200];
Vector3 pos;
PrepareControllerGlyph(nEye, controller, &pos);
if (controller == seconddevice) {
if (selectedAtom==-1) { //isos
sprintf (string, "%d", currentiso+1);
} else {
pos /=scaling;
pos-=UserPosition;
pos=Vector3(pos[0], -pos[2], pos[1]);
pos-=Vector3(atoms[currentset][selectedAtom*4+0], atoms[currentset][selectedAtom*4+1], atoms[currentset][selectedAtom*4+2]);
char dis [200];
sprintf (dis, "%0.2fa", pos.length());
int l=strlen (dis);
float *vert;
vert=new float[l*4*(4+3+2)];
for (int i=0;i<l;i++) {
float u=GetTextureCoordinate(dis[i]);
FillVerticesGlyph (vert, i, u);
} //for
short int *ind=FillIndicesGlyph(l);
RenderNumbersControllerGlyph (l, vert, ind, numbersTexture);
return;
} // if
if (selectedAtom==-1)
return;
Vector3 pos;
PrepareControllerGlyph(nEye, controller, &pos);
sprintf (string, "%0.2fa", pos.length());
} //if selectedatom
} else { // if controller == firstdevice
if (selectedAtom==-1) { //timestep
sprintf (string, "%d", currentset+1);
} else {
//display atom number
char atom [200];
sprintf (atom, "%d", selectedAtom+1);
sprintf (string, "%d", selectedAtom+1);
//sprintf (atom, "%d %.2f %.2f %.2f", selectedAtom+1, atoms[currentset][selectedAtom*4+0], atoms[currentset][selectedAtom*4+1], atoms[currentset][selectedAtom*4+2]);
int l=strlen (atom);
}
}
int l=strlen (string);
float *vert;
vert=new float[l*4*(4+3+2)];
for (int i=0;i<l;i++) {
float u=GetTextureCoordinate(atom[i]);
float u=GetTextureCoordinate(string[i]);
FillVerticesGlyph (vert, i, u);
}
......@@ -2814,7 +2907,7 @@ void CMainApplication::RenderScene(vr::Hmd_Eye nEye)
PaintGrid(nEye, i);
} //for all isos in descending order
if ((e = glGetError()) != GL_NO_ERROR)
dprintf("Gl error after paintgrid: %d, %s\n", e, gluErrorString(e));
dprintf("Gl error after paintgrid within RenderScene: %d, %s\n", e, gluErrorString(e));
if (numAtoms!=0) {
if (menubutton == Infobox && savetodisk)
RenderInfo(nEye);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment