DWORD SpoutSenderSDK2::ProcessOpenGL(ProcessOpenGLStruct *pGL) { // We need a texture to process if (pGL->numInputTextures < 1) return FF_FAIL; if (pGL->inputTextures[0] == NULL) return FF_FAIL; FFGLTextureStruct &InputTexture = *(pGL->inputTextures[0]); // get the max s,t that correspond to the width, height // of the used portion of the allocated texture space FFGLTexCoords maxCoords = GetMaxGLTexCoords(InputTexture); // Draw now whether a sender has initialized or not DrawTexture(InputTexture.Handle, maxCoords); // If there is no sender name yet, the sender cannot be created if(!UserSenderName[0]) { return FF_SUCCESS; // keep waiting for a name } // Otherwise create a sender if not initialized yet else if(!bInitialized) { // Update the sender name strcpy_s(SenderName, 256, UserSenderName); // Set global width and height so any change can be tested m_Width = (unsigned int)InputTexture.Width; m_Height = (unsigned int)InputTexture.Height; // Create a new sender bInitialized = sender.CreateSender(SenderName, m_Width, m_Height); if(!bInitialized) { sender.spout.SelectSenderPanel("Could not create sender\nTry another name"); UserSenderName[0] = 0; // wait for another name to be entered } return FF_SUCCESS; // give it one frame to initialize } // Has the texture size or user entered sender name changed else if(m_Width != (unsigned int)InputTexture.Width || m_Height != (unsigned int)InputTexture.Height || strcmp(SenderName, UserSenderName) != 0 ) { // Release existing sender sender.ReleaseSender(); bInitialized = false; return FF_SUCCESS; // return for initialization on the next frame } // Render the Freeframe texture into the shared texture // Important - pass the FFGL host FBO to restore the binding because Spout uses a local fbo // Default aspect = 1.0, default invert flag = true if(bMemoryMode) sender.SendTexture(InputTexture.Handle, GL_TEXTURE_2D, m_Width, m_Height); else sender.DrawToSharedTexture(InputTexture.Handle, GL_TEXTURE_2D, m_Width, m_Height, (float)maxCoords.s, (float)maxCoords.t, 1.0f, true, pGL->HostFBO); return FF_SUCCESS; }
DWORD FFGLTile::ProcessOpenGL(ProcessOpenGLStruct *pGL) { if (pGL->numInputTextures<1) return FF_FAIL; if (pGL->inputTextures[0]==NULL) return FF_FAIL; //activate our shader m_shader.BindShader(); FFGLTextureStruct &Texture = *(pGL->inputTextures[0]); //activate rendering with the input texture //note that when using shaders, no glEnable(Texture.Target) is required glBindTexture(GL_TEXTURE_2D, Texture.Handle); //get the max s,t that correspond to the //width,height of the used portion of the allocated texture space FFGLTexCoords maxCoords = GetMaxGLTexCoords(Texture); //assign the maxCoords value in the shader //(glUniform2f assigns to a vec2) m_extensions.glUniform2fARB(m_maxCoordsLocation, maxCoords.s, maxCoords.t); //assign the tileAmount m_extensions.glUniform2fARB(m_tileAmountLocation, 20.0*m_TileX, 20.0*m_TileY); //draw the quad that will be painted by the shader/texture glBegin(GL_QUADS); //lower left glTexCoord2f(0,0); glVertex2f(-1,-1); //upper left glTexCoord2f(0, maxCoords.t); glVertex2f(-1,1); //upper right glTexCoord2f(maxCoords.s, maxCoords.t); glVertex2f(1,1); //lower right glTexCoord2f(maxCoords.s, 0); glVertex2f(1,-1); glEnd(); //unbind the shader and texture glBindTexture(GL_TEXTURE_2D, 0); m_shader.UnbindShader(); return FF_SUCCESS; }
DWORD FFGLStatic::ProcessOpenGL(ProcessOpenGLStruct *pGL) { // If no calls to SetTime have been made, the host probably // doesn't support Time, so we'll update m_time manually if (!hastime) { update_time(&m_time, t0); } FFGLTextureStruct &Texture = *(pGL->inputTextures[0]); FFGLTexCoords maxCoords = GetMaxGLTexCoords(Texture); //activate our shader m_shader.BindShader(); //get the max s,t that correspond to the //width,height of the used portion of the allocated texture space float foo = (m_time+float(rand()%100)); m_extensions.glUniform1fARB(m_timeLocation, foo); m_extensions.glUniform1iARB(m_grayscaleLocation, m_mode>0.33f?true:false); m_extensions.glUniform1iARB(m_twotoneLocation, m_mode>0.66f?true:false); glEnable(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D, Texture.Handle); glBegin(GL_QUADS); //lower left glTexCoord2f(0, 0); glVertex2f(-1.0, -1.0); //upper left glTexCoord2f(0, maxCoords.t); glVertex2f(-1.0, 1.0); //upper right glTexCoord2f(maxCoords.s, maxCoords.t); glVertex2f(1.0, 1.0); //lower right glTexCoord2f(maxCoords.s, 0); glVertex2f(1.0, -1.0); glEnd(); //unbind the shader m_shader.UnbindShader(); return FF_SUCCESS; }
DWORD FFGLLumaKey::ProcessOpenGL(ProcessOpenGLStruct *pGL) { if (pGL->numInputTextures<2) return FF_FAIL; if (pGL->inputTextures[0]==NULL) return FF_FAIL; if (pGL->inputTextures[1]==NULL) return FF_FAIL; //activate our shader m_shader.BindShader(); FFGLTextureStruct &TextureDest = *(pGL->inputTextures[0]); FFGLTextureStruct &TextureSrc = *(pGL->inputTextures[1]); //activate rendering with the input texture //note that when using shaders, no glEnable(Texture.Target) is required m_extensions.glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, TextureDest.Handle); m_extensions.glActiveTexture(GL_TEXTURE1); glBindTexture(GL_TEXTURE_2D, TextureSrc.Handle); //get the max s,t that correspond to the //width,height of the used portion of the allocated texture space FFGLTexCoords maxCoords = GetMaxGLTexCoords(TextureDest); //assign the LumaKeyAmount m_extensions.glUniform1fARB(m_LumaLocation, m_Luma); //draw the quad that will be painted by the shader/texture glBegin(GL_QUADS); //lower left glTexCoord2f(0,0); glVertex2f(-1,-1); //upper left glTexCoord2f(0, maxCoords.t); glVertex2f(-1,1); //upper right glTexCoord2f(maxCoords.s, maxCoords.t); glVertex2f(1,1); //lower right glTexCoord2f(maxCoords.s, 0); glVertex2f(1,-1); glEnd(); //unbind the shader and texture m_shader.UnbindShader(); //GL_TEXTURE1 is still active //m_extensions.glActiveTexture(GL_TEXTURE1); glBindTexture(GL_TEXTURE_2D, 0); m_extensions.glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, 0); return FF_SUCCESS; }
DWORD FFGLHeat::ProcessOpenGL(ProcessOpenGLStruct *pGL) { if (pGL->numInputTextures<1) return FF_FAIL; if (pGL->inputTextures[0]==NULL) return FF_FAIL; //activate our shader m_shader.BindShader(); //bind the heat texture to texture unit 0 glBindTexture(GL_TEXTURE_1D, m_heatTextureId); FFGLTextureStruct &Texture = *(pGL->inputTextures[0]); //get the max s,t that correspond to the //width,height of the used portion of the allocated texture space FFGLTexCoords maxCoords = GetMaxGLTexCoords(Texture); //assign the maxCoords value in the shader //(glUniform2f assigns to a vec2) m_extensions.glUniform2fARB(m_maxCoordsLocation, maxCoords.s, maxCoords.t); //assign the heatAmount m_extensions.glUniform1fARB(m_heatAmountLocation, 2.0*m_Heat); //activate texture unit 1 and bind the input texture m_extensions.glActiveTexture(GL_TEXTURE1); glBindTexture(GL_TEXTURE_2D, Texture.Handle); //draw the quad that will be painted by the shader/textures //note that we are sending texture coordinates to texture unit 1.. //the vertex shader and fragment shader refer to this when querying for //texture coordinates of the inputTexture glBegin(GL_QUADS); //lower left m_extensions.glMultiTexCoord2f(GL_TEXTURE1, 0,0); glVertex2f(-1,-1); //upper left m_extensions.glMultiTexCoord2f(GL_TEXTURE1, 0, maxCoords.t); glVertex2f(-1,1); //upper right m_extensions.glMultiTexCoord2f(GL_TEXTURE1, maxCoords.s, maxCoords.t); glVertex2f(1,1); //lower right m_extensions.glMultiTexCoord2f(GL_TEXTURE1, maxCoords.s, 0); glVertex2f(1,-1); glEnd(); //unbind the input texture glBindTexture(GL_TEXTURE_2D, 0); //switch to texture unit 0 and unbind the 1D heat texture m_extensions.glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_1D, 0); //unbind the shader m_shader.UnbindShader(); return FF_SUCCESS; }
DWORD SpoutSenderSDK2::ProcessOpenGL(ProcessOpenGLStruct *pGL) { // We need a texture to process if (pGL->numInputTextures < 1) return FF_FAIL; if (pGL->inputTextures[0] == NULL) return FF_FAIL; FFGLTextureStruct &InputTexture = *(pGL->inputTextures[0]); // get the max s,t that correspond to the width, height // of the used portion of the allocated texture space FFGLTexCoords maxCoords = GetMaxGLTexCoords(InputTexture); // Draw now whether a sender has initialized or not DrawTexture(InputTexture.Handle, maxCoords); // If there is no sender name yet, the sender cannot be created if(!UserSenderName[0]) { return FF_SUCCESS; // keep waiting for a name } // Otherwise create a sender if not initialized yet else if(!bInitialized) { // Update the sender name strcpy_s(SenderName, 256, UserSenderName); // Set global width and height so any change can be tested m_Width = (unsigned int)InputTexture.Width; m_Height = (unsigned int)InputTexture.Height; // Create a new sender bInitialized = sender.CreateSender(SenderName, m_Width, m_Height); if(!bInitialized) { char temp[256]; sprintf(temp,"Could not create sender\n%s\nTry another name", SenderName); MessageBox(NULL, temp, "Spout", MB_OK); UserSenderName[0] = 0; // wait for another name to be entered } return FF_SUCCESS; // give it one frame to initialize } // Has the texture size or user entered sender name changed else if(m_Width != (unsigned int)InputTexture.Width || m_Height != (unsigned int)InputTexture.Height || strcmp(SenderName, UserSenderName) != 0 ) { // Release existing sender sender.ReleaseSender(); bInitialized = false; return FF_SUCCESS; // return for initialization on the next frame } // Now we can send the FFGL texture SaveOpenGLstate(); // Render the Freeframe texture into the shared texture sender.DrawToSharedTexture(InputTexture.Handle, GL_TEXTURE_2D, m_Width, m_Height, (float)maxCoords.s, (float)maxCoords.t); RestoreOpenGLstate(); // Important - Restore the FFGL host FBO binding because Spout uses a local fbo if(pGL->HostFBO) glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, pGL->HostFBO); return FF_SUCCESS; }
DWORD FFGLVolumeRendering::ProcessOpenGL(ProcessOpenGLStruct *pGL) { if (pGL->numInputTextures<1) return FF_FAIL; if (pGL->inputTextures[0]==NULL) return FF_FAIL; FFGLTextureStruct &Texture = *(pGL->inputTextures[0]); //enable texturemapping glEnable(GL_TEXTURE_2D); //bind the texture handle glBindTexture(GL_TEXTURE_2D, Texture.Handle); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); //get the max s,t that correspond to the //width,height of the used portion of the allocated texture space FFGLTexCoords maxCoords = GetMaxGLTexCoords(Texture); glEnable(GL_BLEND); glBlendFunc(GL_SRC_COLOR, GL_ONE_MINUS_SRC_COLOR); glMatrixMode(GL_PROJECTION); // Saving the projection matrix glPushMatrix(); glLoadIdentity(); // Setting parallel projection if (this->fIsPerspective == 0) glOrtho(-1,1,-1,1,-2,2); else { gluPerspective( 90.0*(this->fAngle + 0.5) , 1, 0.1, 100.0); gluLookAt( 0, 0, 1.5, 0, 0, 0, 0, 1, 0 ); } float xRotationAngle = (this->fXAngle - 0.5) * 180; float yRotationAngle = (this->fYAngle - 0.5) * 180; glRotatef(xRotationAngle, 1, 0, 0); glRotatef(yRotationAngle, 0, 1, 0); glScalef(this->fScaleValue, this->fScaleValue, this->fScaleValue); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); #ifndef USE_VBO if (this->isGeometryRebuildNeeded) { this->isGeometryRebuildNeeded = false; this->iList = glGenLists(1); glNewList( this->iList, GL_COMPILE); if (this->iPlanesCount > 1) { double dZStep = (double)this->fDistance/(double)(this->iPlanesCount - 1); glBegin(GL_QUADS); for (int i=0 ; i < this->iPlanesCount ; i++) { double ZCoord = -(this->fDistance/2) + dZStep * (double)i; //lower left glTexCoord2d(0.0, 0.0); glVertex3f(-1, -1, ZCoord); //upper left glTexCoord2d(0.0, maxCoords.t); glVertex3f(-1, 1, ZCoord); //upper right glTexCoord2d(maxCoords.s, maxCoords.t); glVertex3f(1, 1, ZCoord); //lower right glTexCoord2d(maxCoords.s, 0.0); glVertex3f(1, -1, ZCoord); }; glEnd(); } else {// simple quad: glBegin(GL_QUADS); //lower left glTexCoord2d(0.0, 0.0); glVertex3f(-1, -1, 0); //upper left glTexCoord2d(0.0, maxCoords.t); glVertex3f(-1, 1, 0); //upper right glTexCoord2d(maxCoords.s, maxCoords.t); glVertex3f(1, 1, 0); //lower right glTexCoord2d(maxCoords.s, 0.0); glVertex3f(1, -1, 0); glEnd(); }; glEndList(); } glCallList(this->iList); #else int vertextDataSize = 0; int texcoordDataSize = 0; if (this->isGeometryRebuildNeeded) { this->isGeometryRebuildNeeded = false; this->CreateArrayData(maxCoords); vertextDataSize = 4 * this->iPlanesCount * sizeof(GLVertexTriplet); texcoordDataSize = 4 * this->iPlanesCount * sizeof(GLTexcoords); m_extensions.glBindBufferARB(GL_ARRAY_BUFFER_ARB, vboId); m_extensions.glBufferDataARB(GL_ARRAY_BUFFER_ARB, vertextDataSize + texcoordDataSize, 0, GL_STATIC_DRAW_ARB); m_extensions.glBufferSubDataARB(GL_ARRAY_BUFFER_ARB, 0, vertextDataSize, this->VertexData); // copy vertices starting from 0 offest m_extensions.glBufferSubDataARB(GL_ARRAY_BUFFER_ARB, vertextDataSize, texcoordDataSize, this->TexcoordData); // copy texcoords after vertices; m_extensions.glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0); } m_extensions.glBindBufferARB(GL_ARRAY_BUFFER_ARB, vboId); glEnableClientState(GL_VERTEX_ARRAY); glEnableClientState(GL_TEXTURE_COORD_ARRAY); vertextDataSize = 4 * this->iPlanesCount * sizeof(GLVertexTriplet); texcoordDataSize = 4 * this->iPlanesCount * sizeof(GLTexcoords); glVertexPointer(3, GL_FLOAT, 0, 0); glTexCoordPointer(2, GL_FLOAT, 0, (void*)(vertextDataSize)); glDrawArrays(GL_QUADS, 0, this->iPlanesCount*4); glDisableClientState(GL_VERTEX_ARRAY); glDisableClientState(GL_TEXTURE_COORD_ARRAY); m_extensions.glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0); #endif glMatrixMode(GL_PROJECTION); //Restoring projection matrix glPopMatrix(); //unbind the texture glBindTexture(GL_TEXTURE_2D, 0); //disable texturemapping glDisable(GL_TEXTURE_2D); //disable blending glDisable(GL_BLEND); //restore default color glColor4f(1.f,1.f,1.f,1.f); return FF_SUCCESS; }