#ifndef STIM_GL_SPIDER_H #define STIM_GL_SPIDER_H #include #include #include #include #include #include #include "../gl/gl_texture.h" #include "../visualization/camera.h" #include "./error.h" #include "../math/vector.h" #include "../math/rect.h" #include "../cuda/cost.h" #include "../cuda/glbind.h" #include #include namespace stim { template class gl_spider : public virtual gl_texture { //doen't use gl_texture really, just needs the GLuint id. //doesn't even need the texture iD really. private: stim::vec position; //vector designating the position of the spider. stim::vec direction; //vector designating the orientation of the spider //always a unit vector. stim::vec magnitude; //magnitude of the direction vector. //mag[0] = length. //mag[1] = width. using gl_texture::texID; //using image_stack::S; cudaArray* c_Array; //void** devPtr; //size_t size; cudaGraphicsResource_t resource; GLuint fboID; GLuint texbufferID; int iter = 0; void findOptimalPosition() { /* Method for finding the best direction for the spider. Not sure if necessary since the next position for the spider will be at direction * magnitude. */ } void findOptimalScale() { /* Method for finding the best scale for the spider. changes the x, y, z size of the spider to minimize the cost function. */ } void Evaluate() { /* Uses uniform sampler2D in order to take a difference between the colors of two textures. 1st texture is the spider template, the 2nd is the location of the spider's overlap with the gl_template does the spider need to track it's location? Prob not since position can be set with gl_texture coordinates */ } void Optimize() { /*find the optimum direction and scale */ } /* void Step() { // move to the new position } */ void GenerateFBO(unsigned int width, unsigned int height) { glGenFramebuffers(1, &fboID); glBindFramebuffer(GL_FRAMEBUFFER, fboID); int numChannels = 1; unsigned char* texels = new unsigned char[width * height * numChannels]; glGenTextures(1, &texbufferID); glBindTexture(GL_TEXTURE_2D, texbufferID); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, width, height, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, texels); delete[] texels; glBindFramebuffer(GL_FRAMEBUFFER, 0); glBindTexture(GL_TEXTURE_2D, 0); } void UpdateBuffer(float v_x, float v_y) { //std::cout << v_y << std::endl; float len = 10.0; stim::vecp1; stim::vecp2; stim::vecp3; stim::vecp4; p1 = hor.p(1,1); p2 = hor.p(1,0); p3 = hor.p(0,0); p4 = hor.p(0,1); glBegin(GL_QUADS); glTexCoord3f( p1[0], p1[1], p1[2] ); //glVertex2f(0.0,0.0); glVertex2f(v_x,v_y); glTexCoord3f( p2[0], p2[1], p2[2] ); //glVertex2f(1.0, 0.0); glVertex2f(v_x+len, v_y); glTexCoord3f( p3[0], p3[1], p3[2] ); //glVertex2f(1.0, 2.0); glVertex2f(v_x+len, v_y+len); glTexCoord3f( p4[0], p4[1], p4[2] ); //glVertex2f(0.0, 2.0); glVertex2f(v_x, v_y+len); glEnd(); p1 = ver.p(1,1); p2 = ver.p(1,0); p3 = ver.p(0,0); p4 = ver.p(0,1); glBegin(GL_QUADS); glTexCoord3f( p1[0], p1[1], p1[2] ); //glVertex2f(1.0, 0.0); glVertex2f(v_x+len, v_y); glTexCoord3f( p2[0], p2[1], p2[2] ); //glVertex2f(2.0, 0.0); glVertex2f(v_x+2*len, v_y); glTexCoord3f( p3[0], p3[1], p3[2] ); //glVertex2f(2.0, 2.0); glVertex2f(v_x+2*len, v_y+len); glTexCoord3f( p4[0], p4[1], p4[2] ); //glVertex2f(1.0, 2.0); glVertex2f(v_x+len, v_y+len); glEnd(); } void Update(float v_x, float v_y, vec dir) { vec Y(1.0,0.0,0.0); if(cos(Y.dot(dir))< 0.087){ Y[0] = 0.0; Y[1] = 1.0;} hor = stim::rect(magnitude, position, dir.norm(), ((Y.cross(dir)).cross(dir)).norm()); ver = stim::rect(magnitude, position, dir.norm(), hor.n()); UpdateBuffer(v_x, v_y); } void Sample(vec in = (0,0,1), int numSamples = 1089, int solidAngle = M_PI/2) { GenerateFBO(20, numSamples*10); ofstream file; file.open("samples.txt", std::ios_base::app); float samples[numSamples][3]; //Set up the variables //necessary for sample generation vec d_s = in.cart2sph(); vec temp; int dim = (sqrt(numSamples)-1)/2; //std::cout << dim << std::endl; float y_0 = 0.0; float len = 10.0; float p0 = M_PI/3; float dt = solidAngle/(1.0 * dim); float dp = p0/(1.0*dim); glBindFramebuffer(GL_FRAMEBUFFER, fboID);//set up GL buffer glFramebufferTexture2D( GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texbufferID, 0); glBindFramebuffer(GL_FRAMEBUFFER, fboID); GLenum DrawBuffers[1] = {GL_COLOR_ATTACHMENT0}; glDrawBuffers(1, DrawBuffers); glBindTexture(GL_TEXTURE_2D, texbufferID); glClearColor(0,0,0,0); glClear(GL_COLOR_BUFFER_BIT); glMatrixMode(GL_PROJECTION); glLoadIdentity(); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glViewport(0,0,2.0*len, numSamples*len); gluOrtho2D(0.0,2.0*len,0.0,numSamples*len); glEnable(GL_TEXTURE_3D); glBindTexture(GL_TEXTURE_3D, texID); //file << "iteration: " << iter << "\n"; //file << "starting pos and dir:" << "[" << position[0] << "," < next; next[0] = samples[nxt][0]; next[1] = samples[nxt][1]; next[2] = samples[nxt][2]; next.norm(); //file << "next direction" << "[" << next[0] << "," << next[1] << "," << next[2] << "]\n\n"; setPosition(position[0] + next[0]/500, position[1]+next[1]/500, position[2]+next[2]/500); setDirection(next[0], next[1], next[2]); //file.close(); } //--------------------------------------------------------------------------// //--------------------------------CUDA METHODS------------------------------// //--------------------------------------------------------------------------// /* Method for registering the texture with Cuda for shared access */ void createResource() { HANDLE_ERROR( cudaGraphicsGLRegisterImage( &resource, texbufferID, GL_TEXTURE_2D, //CU_GRAPHICS_REGISTER_FLAGS_NONE) cudaGraphicsMapFlagsReadOnly) ); } /* Method for freeing the texture from Cuda for gl access */ void destroyResource() { HANDLE_ERROR( cudaGraphicsUnregisterResource(resource) ); } /* Entry-point into the cuda code for calculating the cost of a given samples array (in texture form) */ int getCost() { createResource(); int cost = get_cost(resource, iter); destroyResource(); iter++; return cost; } public: stim::rect hor; stim::rect ver; gl_spider () { setPosition(0.0,0.0,0.0); setDirection(1.0,1.0,1.0); setMagnitude(0.1,0.1); //GenerateFBO(400,200); //Update(); } gl_spider (vec pos, vec dir, vec mag) { position = pos; direction = dir; magnitude = mag; //GenerateFBO(400,200); //Update(); } //temporary cost for convenience. gl_spider (float pos_x, float pos_y, float pos_z, float dir_x, float dir_y, float dir_z, float mag_x, float mag_y) { setPosition(pos_x, pos_y, pos_z); setDirection(dir_x, dir_y, dir_z); setMagnitude(mag_x, mag_y); //GenerateFBO(400,200); //Update(); } void attachSpider(GLuint id) { texID = id; Sample(direction); //GenerateFBO(20,10000); // Update(); // generateVectorField(direction, 4.0); } void Update() { vec Y(1.0,0.0,0.0); if(cos(Y.dot(direction))< 0.087){ Y[0] = 0.0; Y[1] = 1.0;} hor = stim::rect(magnitude, position, direction.norm(), ((Y.cross(direction)).cross(direction)).norm()); ver = stim::rect(magnitude, position, direction.norm(), hor.n()); //UpdateBuffer(); generateVectorField(direction, 4.0); } vec getPosition() { return position; } vec getDirection() { return direction; } vec getMagnitude() { return magnitude; } void setPosition(vec pos) { position = pos; } void setPosition(float x, float y, float z) { position[0] = x; position[1] = y; position[2] = z; } void setDirection(vec dir) { direction = dir; } void setDirection(float x, float y, float z) { direction[0] = x; direction[1] = y; direction[2] = z; } void setMagnitude(vec mag) { magnitude = mag; } void setMagnitude(float x, float y) { magnitude[0] = x; magnitude[1] = y; } GLuint getFB() { return fboID; } void Step() { std::cout << position[0] << "," << position[1] << "," << position[1] << std::endl; //setPosition(direction*magnitude[1]/2+position); findOptimalDirection(); //Update(); std::cout << position[0] << "," << position[1] << "," << position[1] << std::endl; } void UpdateBuffer() { stim::vecp1; stim::vecp2; stim::vecp3; stim::vecp4; glBindFramebuffer(GL_FRAMEBUFFER, fboID); glFramebufferTexture2D( GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texbufferID, 0); glBindFramebuffer(GL_FRAMEBUFFER, fboID); GLenum DrawBuffers[1] = {GL_COLOR_ATTACHMENT0}; glDrawBuffers(1, DrawBuffers); glBindTexture(GL_TEXTURE_2D, texbufferID); glClearColor(0,0,0,0); glClear(GL_COLOR_BUFFER_BIT); glMatrixMode(GL_PROJECTION); glLoadIdentity(); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glViewport(0,0,400,200); gluOrtho2D(0.0,2.0,0.0,2.0); glEnable(GL_TEXTURE_3D); glBindTexture(GL_TEXTURE_3D, texID); p1 = hor.p(1,1); p2 = hor.p(1,0); p3 = hor.p(0,0); p4 = hor.p(0,1); glBegin(GL_QUADS); glTexCoord3f( p1[0], p1[1], p1[2] ); glVertex2f(0.0,0.0); glTexCoord3f( p2[0], p2[1], p2[2] ); glVertex2f(1.0, 0.0); glTexCoord3f( p3[0], p3[1], p3[2] ); glVertex2f(1.0, 2.0); glTexCoord3f( p4[0], p4[1], p4[2] ); glVertex2f(0.0, 2.0); glEnd(); p1 = ver.p(1,1); p2 = ver.p(1,0); p3 = ver.p(0,0); p4 = ver.p(0,1); glBegin(GL_QUADS); glTexCoord3f( p1[0], p1[1], p1[2] ); glVertex2f(1.0, 0.0); glTexCoord3f( p2[0], p2[1], p2[2] ); glVertex2f(2.0, 0.0); glTexCoord3f( p3[0], p3[1], p3[2] ); glVertex2f(2.0, 2.0); glTexCoord3f( p4[0], p4[1], p4[2] ); glVertex2f(1.0, 2.0); glEnd(); glBindTexture(GL_TEXTURE_3D, 0); glDisable(GL_TEXTURE_3D); glBindFramebuffer(GL_FRAMEBUFFER,0); glBindTexture(GL_TEXTURE_2D, 0); } void generateVectorField(stim::vec d, float dim) { vec d_s = d.cart2sph(); vec temp; float Dim = (float) dim; float y_0 = 0.0; float x_0 = 0.0; float len = 4.0/(2.0*Dim+1.0); float t0 = M_PI/2; float p0 = M_PI/3; float dt = t0/Dim; float dp = p0/Dim; for(int i = -dim; i <= dim; i++){ for(int j = -dim; j <= dim; j++){ //field[i+dim][j+dim][0] = d[0]; //field[i+dim][j+dim][1] = d[1]+dt*i; //field[i+dim][j+dim][2] = d[2]+dp*j; temp[0] = 1; temp[1] = d_s[1]+dt*i; temp[2] = d_s[2]+dp*j; temp = temp.sph2cart(); Update(x_0+2.0*(i+dim)*len, y_0+(j+dim)*len, temp); } } } void findOptimalDirection() { /* Method for finding the best direction for the spider. Uses the camera to rotate. Then Calls Evaluate to find new cost. */ Sample(direction); } /* Method for initializing the cuda devices, necessary only there are multiple cuda devices */ void initCuda() { //stim::cudaSetDevice(); //GLint max; //glGetIntegerv(GL_MAX_TEXTURE_SIZE, &max); //std::cout << max << std::endl; } }; } #endif