#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 #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. std::vector > dirVectors; std::vector > posVectors; std::vector > magVectors; using gl_texture::texID; using gl_texture::S; cudaArray* c_Array; //void** devPtr; //size_t size; cudaGraphicsResource_t resource; GLuint fboID; GLuint texbufferID; int iter; //temporary for testing int numSamples; 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. */ getSample(position, direction, magnitude); int best = getCost(); } 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. */ genTemplate(magVectors, 2); int best = getCost(); } void findOptimalDirection() { /* Method for finding the best scale for the spider. changes the x, y, z size of the spider to minimize the cost function. */ genTemplate(dirVectors, 0); //getSample(position, direction, magnitude); //int best = getCost(); } void Optimize() { /*find the optimum direction and scale */ } ///@param width sets the width of the buffer. ///@param height sets the height of the buffer. ///Function for setting up the 2D buffer that stores the samples. 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); } ///@param v_x x-coordinate in buffer-space, ///@param v_y y-coordinate in buffer-space. ///Samples the texturespace and places a sample in the provided coordinates ///of bufferspace. 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; std::cout << "hor" << std::endl; p1 = hor.p(1,1); std::cout << p1 << std::endl; p2 = hor.p(1,0); std::cout << p2 << std::endl; p3 = hor.p(0,0); std::cout << p3 << std::endl; p4 = hor.p(0,1); std::cout << p4 << std::endl; /* glBegin(GL_QUADS); glTexCoord3f( // p1[0]/S[1], // p1[1]/S[2], // p1[2]/S[3] // ); p1[0], p1[1], p1[2] ); CHECK_OPENGL_ERROR //glVertex2f(0.0,0.0); glVertex2f(v_x,v_y); glTexCoord3f( // p2[0]/S[1], // p2[1]/S[2], // p2[2]/S[3] p2[0], p2[1], p2[2] ); //glVertex2f(1.0, 0.0); glVertex2f(v_x+len, v_y); glTexCoord3f( // p2[0]/S[1], // p2[1]/S[2], // p2[2]/S[3] p3[0], p3[1], p3[2] ); //glVertex2f(1.0, 2.0); glVertex2f(v_x+len, v_y+len); glTexCoord3f( // p4[0]/S[1], // p4[1]/S[2], // p4[2]/S[3] p4[0], p4[1], p4[2] ); //glVertex2f(0.0, 2.0); glVertex2f(v_x, v_y+len); glEnd(); */ std::cout << "ver" << std::endl; p1 = ver.p(1,1); std::cout << p1 << std::endl; p2 = ver.p(1,0); std::cout << p2 << std::endl; p3 = ver.p(0,0); std::cout << p3 << std::endl; p4 = ver.p(0,1); std::cout << p4 << std::endl; /* glBegin(GL_QUADS); glTexCoord3f( // p1[0]/S[1], // p1[1]/S[2], // p1[2]/S[3] p1[0], p1[1], p1[2] ); //glVertex2f(1.0, 0.0); glVertex2f(v_x+len, v_y); glTexCoord3f( // p2[0]/S[1], // p2[1]/S[2], // p2[2]/S[3] p2[0], p2[1], p2[2] ); //glVertex2f(2.0, 0.0); glVertex2f(v_x+2*len, v_y); glTexCoord3f( // p3[0]/S[1], // p3[1]/S[2], // p3[2]/S[3] p3[0], p3[1], p3[2] ); //glVertex2f(2.0, 2.0); glVertex2f(v_x+2*len, v_y+len); glTexCoord3f( // p4[0]/S[1], // p4[1]/S[2], // p4[2]/S[3] p4[0], p4[1], p4[2] ); //glVertex2f(1.0, 2.0); glVertex2f(v_x+len, v_y+len); glEnd(); */ } ///@param vector of stim::vec in that stores all of the samplable vectors. ///@param type, one of three operations, 0 for Direction vectors /// 1 for Position, 2 for Magnitude. ///Function for filling the buffer up with the data based on the vectors ///Each vector represents a two rectangular templates. ///Loops through all of the vectors and transfers rect. associated with it ///Into buffer-space. void genTemplate(std::vector > in, int type) { float x = 0.0; vec Y(1.0,0.0,0.0); switch(type) { case 0: //Direction Bind(); for(int i = 0; i < in.size(); i++) { if(cos(Y.dot(in[i]))< 0.087){ Y[0] = 0.0; Y[1] = 1.0;} else{Y[0] = 1.0; Y[1] = 0.0;} hor = stim::rect(magnitude, position, in[i], ((Y.cross(in[i])).cross(in[i])).norm()); ver = stim::rect(magnitude, position, in[i], hor.n()); UpdateBuffer(x, x+i*10.0); } Unbind(); std::cout<< "Hmmm" << std::endl; break; case 1: //Position Bind(); if(cos(Y.dot(direction))< 0.087){ Y[0] = 0.0; Y[1] = 1.0;} else{Y[0] = 1.0; Y[1] = 0.0;} for(int i = 0; i < in.size(); i++) { hor = stim::rect(magnitude, in[i], direction, ((Y.cross(direction)).cross(direction)) .norm()); ver = stim::rect(magnitude, in[i], direction, hor.n()); //UpdateBuffer(x, x+i*10.0); std::cout<< "Hmmm" << std::endl; } Unbind(); break; case 2: //Scale Bind(); if(cos(Y.dot(direction))< 0.087){ Y[0] = 0.0; Y[1] = 1.0;} else{Y[0] = 1.0; Y[1] = 0.0;} for(int i = 0; i < in.size(); i++) { hor = stim::rect(in[i], position, direction, ((Y.cross(direction)).cross(direction)) .norm()); ver = stim::rect(in[i], position, direction, hor.n()); //UpdateBuffer(x, x+i*10.0); std::cout<< "Hmmm" << std::endl; } Unbind(); break; default: std::cout << "unknown case have been passed" << std::endl; break; } Unbind(); CHECK_OPENGL_ERROR } ///Method for controling the buffer and texture binding in order to properly ///do the render to texture. void Bind() { float len = 10.0; 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); } ///Method for Unbinding all of the texture resources void Unbind() { //Finalize GL_buffer glBindTexture(GL_TEXTURE_3D, 0); glDisable(GL_TEXTURE_3D); glBindFramebuffer(GL_FRAMEBUFFER,0); glBindTexture(GL_TEXTURE_2D, 0); } ///@param solidAngle, the size of the arc to sample. ///Method for populating the vector arrays with sampled vectors. ///uses the default direction vector <0,0,1> void genDirectionVectors(float solidAngle = M_PI/2) { vec d_s = direction.cart2sph().norm(); //dirVectors.resize(numSamples); //THIS LINE ADDS AN ERROR vec temp; int dim = (sqrt(numSamples)-1)/2; float p0 = M_PI/3; float dt = solidAngle/(2.0 * (dim + 1)); float dp = p0/(2.0*(dim + 1)); for(int i = -dim; i <= dim; i++){ for(int j = -dim; j <= dim; j++){ //Create linear index temp[0] = d_s[0]; //rotate vector temp[1] = d_s[1]+dt*i; temp[2] = d_s[2]+dp*j; temp = (temp.sph2cart()).norm(); //back to cart std::cout << temp << std::endl; dirVectors.push_back(temp); } } } ///@param solidAngle, the size of the arc to sample. ///Method for populating the buffer with the sampled texture. ///uses the default vector <0,0,0> void genPositionVectors(float delta = 0.2) { vec temp; int dim = (sqrt(numSamples)-1)/2; stim::rect samplingPlane = stim::rect(magnitude[0]*delta, position, direction); float step = 1.0/(dim); //Loop over the samples, keeping the original position sample //in the center of the resulting texture. int idx; for(int i = -dim; i <= dim; i++){ for(int j = -dim; j <= dim; j++){ //Create linear index temp = samplingPlane.p( 0.5+step*i, 0.5+step*j ); posVectors.push_back(temp); } } } ///@param solidAngle, the size of the arc to sample. ///Method for populating the buffer with the sampled texture. ///uses the default magnitude <1,1,0> void genMagnitudeVectors(float delta = 0.5) { int dim = (sqrt(numSamples)-1)/2; float min = 1.0-delta; float max = 1.0+delta; float step = (max-min)/(numSamples-1); float factor; vec temp; for(int i = 0; i < numSamples; i++){ //Create linear index factor = (min+step*i)*magnitude[0]; temp[0] = factor; temp[1] = factor; magVectors.push_back(temp); } } //--------------------------------------------------------------------------// //--------------------------------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; ///Default Constructor gl_spider () { setPosition(0.0,0.0,0.0); setDirection(0.0,0.0,1.0); setMagnitude(1.0); //numSamples = 1089; numSamples = 9; std::cout << "I did this" <::setDims(0.6, 0.6, 2.0); genTemplate(dirVectors, 0); //gl_texture::setDims(1.0, 1.0,1.0); } ///temporary Method necessary for visualization and testing. 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()); } ///Returns the position vector. vec getPosition() { return position; } ///Returns the direction vector. vec getDirection() { return direction; } ///Returns the magnitude vector. vec getMagnitude() { return magnitude; } ///@param vector pos, the new position. ///Sets the position vector to input vector pos. void setPosition(vec pos) { position = pos; } ///@param x x-coordinate. ///@param y y-coordinate. ///@param z z-coordinate. ///Sets the position vector to the input float coordinates x,y,z. void setPosition(float x, float y, float z) { position[0] = x; position[1] = y; position[2] = z; } void getSample(vec pos, vec dir, vec mag) { Bind(); glMatrixMode(GL_TEXTURE); glLoadIdentity(); vec temp = dir.sph2cart(); glScalef(mag[0], mag[1], mag[0]); //glRotatef(rotz, 0.0, 0.0, 1.0); //glRotatef(roty, 0.0, 1.0, 0.0); //glRotatef(rotx, 1.0, 0.0 ,0.0); glTranslatef(pos[0], pos[1], pos[2]); glScalef(1/512/S[0], 1/512/S[1], 1/426/S[2]); Unbind(); } ///@param vector dir, the new direction. ///Sets the direction vector to input vector dir. void setDirection(vec dir) { direction = dir; } ///@param x x-coordinate. ///@param y y-coordinate. ///@param z z-coordinate. ///Sets the direction vector to the input float coordinates x,y,z. void setDirection(float x, float y, float z) { direction[0] = x; direction[1] = y; direction[2] = z; } ///@param vector dir, the new direction. ///Sets the magnitude vector to the input vector mag. void setMagnitude(vec mag) { magnitude[0] = mag[0]; magnitude[1] = mag[0]; } ///@param mag size of the sampled region. ///Sets the magnitude vector to the input mag for both templates. void setMagnitude(float mag) { magnitude[0] = mag; magnitude[1] = mag; } ///temporary method for visualization. GLuint getFB() { return fboID; } void Step() { findOptimalDirection(); } /* 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