A3DMatrix operator * (const A3DMatrix& mat1, const A3DMatrix& mat2) { A3DMatrix mat; MatrixMul(mat, mat1, mat2, 4); mat.Normalise(); return mat; }
int main(int argc, char ** argv) { char op; char mStr[1024]; matrix ans, m1, m2; int sc = 0; if(argc > 1){ op = getOp(argv[1]); } else { printf("Which operation: "); op = getOp(NULL); } printf("First matrix:\n"); scanf("%s", mStr); m1 = MatrixInit(mStr); if(op == 'a' || op == 's' || op == 'm'){ printf("Second matrix:\n"); scanf("%s", mStr); m2 = MatrixInit(mStr); } else if(op == 'c') { printf("Scalar multiple:\n"); scanf("%d", &sc); } switch(op){ case 'a': ans = MatrixAdd(m1, m2); break; case 's': ans = MatrixSub(m1, m2); break; case 'm': ans = MatrixMul(m1, m2); break; case 'i': ans = MatrixInv(m1); break; case 'c': ans = MatrixSMul(m1, i2f(sc)); break; default: printf("Something went very wrong.\n"); return 1; } printf("Answer:\n"); MatrixPrint(ans); MatrixFree(m1); MatrixFree(ans); if(op == 'a' || op == 's' || op == 'm'){ MatrixFree(m2); } return 0; }
int main(int argc, char *argv[]) { int A[2][2]={1,1,1,1}; int B[2][2]={1,1,1,1}; printf("%d ",MatrixMul(A,B)); return 0; }
A3DMatrix& A3DMatrix::operator *= (double val) { if (val != 1.0) { A3DMatrix mat; mat.a11 = mat.a22 = mat.a33 = val; MatrixMul(*this, *this, mat, 4); Normalise(); } return *this; }
//============================================================================// //== 卡尔曼滤波 ==// //============================================================================// //==入口参数: 无 ==// //==出口参数: 无 ==// //==返回值: 无 ==// //============================================================================// void KalMan(void) { unsigned char i; unsigned short j; srand(SEED); for (i=0; i<X_LENGTH; i++) { tOpt.XPreOpt[i] = Temp2[i]; //零值初始化 } for (i=0; i<P_LENGTH; i++) { tCov.PPreOpt[i] = Temp4[i]; //零值初始化 } for (j=0; j<N; j++) { Watch1[j] = sin(2*3.14159265/100.0*j); Y[0] = Watch1[j] + Random1(0, 0.4); Watch2[j] = Y[0]; MatrixMul(A, tOpt.XPreOpt, X, A_ROW, X_ROW, X_COLUMN); // 基于系统的上一状态而预测现在状态; X(k|k-1) = A(k,k-1)*X(k-1|k-1) MatrixCal1(A, tCov.PPreOpt, Temp4, SYS_ORDER); MatrixAdd(Temp4, Q, P, P_ROW, P_COLUMN); // 预测数据的协方差矩阵; P(k|k-1) = A(k,k-1)*P(k-1|k-1)*A(k,k-1)'+Q MatrixCal2(C, P, Temp1, C_ROW, C_COLUMN); MatrixAdd(Temp1, R, Temp1, R_ROW, R_COLUMN); Gauss_Jordan(Temp1, C_ROW); MatrixTrans(C, Temp2, C_ROW, C_COLUMN); MatrixMul(P, Temp2, Temp22, P_ROW, C_COLUMN, C_ROW); MatrixMul(Temp22, Temp1, K, P_ROW, C_ROW, C_ROW); // 计算卡尔曼增益; K(k) = P(k|k-1)*C' / (C(k)*P(k|k-1)*C(k)' + R) MatrixMul(C, X, Temp1, C_ROW, X_ROW, X_COLUMN); MatrixMinus(Y, Temp1, Temp1, Y_ROW, Y_COLUMN); MatrixMul(K, Temp1, Temp2, K_ROW, Y_ROW, Y_COLUMN); MatrixAdd(X, Temp2, tOpt.XNowOpt, X_ROW, X_COLUMN); // 根据估测值和测量值计算当前最优值; X(k|k) = X(k|k-1)+Kg(k)*(Y(k)-C*X(k|k-1)) MatrixMul(K, C, Temp4, K_ROW, C_ROW, C_COLUMN); MatrixMinus(I, Temp4, Temp4, I_ROW, I_COLUMN); MatrixMul(Temp4, P, tCov.PNowOpt, I_ROW, P_ROW, P_COLUMN); // 计算更新后估计协防差矩阵; P(k|k) =(I-Kg(k)*C)*P(k|k-1) for (i=0; i<X_LENGTH; i++) { tOpt.XPreOpt[i] = tOpt.XNowOpt[i]; } for (i=0; i<P_LENGTH; i++) { tCov.PPreOpt[i] = tCov.PNowOpt[i]; } Watch3[j] = tOpt.XNowOpt[0]; }//end of for }
/** Multiplies mx by f. * Returns materr(1) if the initialization * of sc didn't go right. */ matrix MatrixSMul(matrix mx, frac f) { matrix sc = initialize(mx.columns, mx.columns); if (sc.mx == NULL) { return materr(1); } for(int i = 0; i < mx.columns; i++) { sc.mx[i][i] = f; } return MatrixMul(mx, sc); }
//============================================================================// //== 卡尔曼滤波 ==// //============================================================================// //==入口参数: 无 ==// //==出口参数: 无 ==// //==返回值: 无 ==// //============================================================================// void KalMan(u16* in,u16* out) { unsigned char i; // unsigned short k; for (i=0; i<LENGTH; i++) { tOpt.XPreOpt[i] = Temp1[i]; //零值初始化 } for (i=0; i<LENGTH; i++) { tCov.PPreOpt[i] = Temp2[i]; //零值初始化 } // for (k=0; k<N; k++) // { Z[0] = in[0];//(float)ADCSampling(); MatrixMul(F, tOpt.XPreOpt, X, ORDER, ORDER, ORDER); // 基于系统的上一状态而预测现在状态; X(k|k-1) = F(k,k-1)*X(k-1|k-1) MatrixCal(F, tCov.PPreOpt, Temp1, ORDER); MatrixAdd(Temp1, Q, P, ORDER, ORDER); // 预测数据的协方差矩阵; P(k|k-1) = F(k,k-1)*P(k-1|k-1)*F(k,k-1)'+Q MatrixCal(H, P, Temp1, ORDER); MatrixAdd(Temp1, R, Temp1, ORDER, ORDER); Gauss_Jordan(Temp1, ORDER); MatrixTrans(H, Temp2, ORDER, ORDER); MatrixMul(P, Temp2, Temp3, ORDER, ORDER, ORDER); MatrixMul(Temp1, Temp3, K, ORDER, ORDER, ORDER); // 计算卡尔曼增益; Kg(k) = P(k|k-1)*H' / (H*P(k|k-1)*H' + R) MatrixMul(H, X, Temp1, ORDER, ORDER, ORDER); MatrixMinus(Z, Temp1, Temp1, ORDER, ORDER); MatrixMul(K, Temp1, Temp2, ORDER, ORDER, ORDER); MatrixAdd(X, Temp2, tOpt.XNowOpt, ORDER, ORDER); // 根据估测值和测量值计算当前最优值; X(k|k) = X(k|k-1)+Kg(k)*(Z(k)-H*X(k|k-1)) MatrixMul(K, H, Temp1, ORDER, ORDER, ORDER); MatrixMinus(I, Temp1, Temp1, ORDER, ORDER); MatrixMul(Temp1, P, tCov.PNowOpt, ORDER, ORDER, ORDER); // 计算更新后估计协防差矩阵; P(k|k) =(I-Kg(k)*H)*P(k|k-1) for (i=0; i<LENGTH; i++) { tOpt.XPreOpt[i] = tOpt.XNowOpt[i]; tCov.PPreOpt[i] = tCov.PNowOpt[i]; } out[0]=(u16)(tOpt.XNowOpt[0]); // } }
VMatrix VMatrix::operator*(const VMatrix &vm) const { VMatrix ret; MatrixMul( vm, ret ); return ret; }
//-------------------main function starts here------------------------------------ void main() { float a[ROW][COL], b[ROW][COL]; int m[2], n[2], choice,i,j,temp; bool flag, flag1=true; //-------------from the following the size of matrix is tested with proper input---------------------- cout<<"Enter the dimention of the 1st matrix :"<<endl; for(i=0;i<2;i++) { flag = false; while(!flag) { cin >> temp; if(temp>0 && !cin.fail() && (cin.peek() == EOF || cin.peek() == '\n')) { flag = true; m[i]=temp; } else { cout << "Please Enter valid data" << endl; cin.clear(); cin.ignore(numeric_limits<streamsize>::max(), '\n'); } } } cout<<"Enter the dimention of the 2nd matrix :"<<endl; for(i=0;i<2;i++) { flag = false; while(!flag) { cin >> temp; if(temp>0 && !cin.fail() && (cin.peek() == EOF || cin.peek() == '\n')) { flag = true; n[i]=temp; } else { cout << "Please Enter valid data" << endl; cin.clear(); cin.ignore(numeric_limits<streamsize>::max(), '\n'); } } } //---------------input for 1st matrix starts here---------------------- cout<<"Enter the 1st matrix"<<endl; for(i=0;i<m[0];i++) { for(j=0;j<m[1];j++) cin>>a[i][j]; } //--------------input for 2nd matrix strts here------------------------- cout<<"Enter the 2nd matrix"<<endl; for(i=0;i<n[0];i++) { for(j=0;j<n[1];j++) cin>>b[i][j]; } //-------------Choice for Matrix operation to select------------------ while(1) { if(!flag1) { exit(0); } cout<<"Select the operation to perform with the above matrix \n 1. Addition\n 2. Subtraction\n 3. Multiplication"<<endl; cin>>choice; switch(choice) { case 1: if(m[0]!=n[0] || m[1]!=n[1]) cout<<"Matrix cannot be added"<<endl; else MatrixAdd(a,b,m); break; case 2: if(m[0]!=n[0] || m[1]!=n[1]) cout<<"Matrix cannot be subtracted"<<endl; else MatrixSub(a,b,m); break; case 3: if(m[1]!=n[0]) cout<<"Matrix cannot be multiplied"; else MatrixMul(a,b,m,n); break; default: cout<<"Invalid Input!!"<<endl; } //-----------------Asked for continuity or to exit------------------------------- cout<<"Enter 1 to try again or else 0 to exit : "; cin>>flag1; } }
void Matrix44::Multiply(const Matrix44 &a, const Matrix44 &b, Matrix44 &result) { MatrixMul(4, a.data, b.data, result.data); }
void Matrix33::Multiply(const Matrix33 &a, const Matrix33 &b, Matrix33 &result) { MatrixMul(3, a.data, b.data, result.data); }
// Draw the scene to the screen void draw() { // Update time time += 2.0f * timeStep; /////////////////////// PART 1: SIMULATION ///////////////////////////////// // Grab buffers for OpenCL acquireGLBuffer(particles.particleBuffer[particles.currentBuffer]); acquireGLBuffer(particles.particleBuffer[1 - particles.currentBuffer]); // Prepare to run some kernels cl_int numParticles = NUM_PARTICLES; cl_int gridElements = GRID_SIZE * GRID_SIZE * GRID_SIZE; cl_uint workSize[3] = {numParticles, 0, 0}; cl_uint gridWorkSize[3] = {gridElements, 0, 0}; cl_uint workgroupSize[3] = {256, 0, 0}; // Clear grid clSetKernelArg(openCLKernels.gridClearKernel, 0, sizeof(cl_mem), &particles.gridSizeBuffer); clSetKernelArg(openCLKernels.gridClearKernel, 1, sizeof(cl_int), &gridElements); clRunKernel(openCLKernels.gridClearKernel, gridWorkSize, workgroupSize); // Compute grid positions clSetKernelArg(openCLKernels.gridKernel, 0, sizeof(cl_mem), &particles.particleBuffer[particles.currentBuffer]); clSetKernelArg(openCLKernels.gridKernel, 1, sizeof(cl_mem), &particles.offsetBuffer); clSetKernelArg(openCLKernels.gridKernel, 2, sizeof(cl_mem), &particles.gridSizeBuffer); clSetKernelArg(openCLKernels.gridKernel, 3, sizeof(cl_int), &numParticles); clRunKernel(openCLKernels.gridKernel, workSize, workgroupSize); // Compute prefix sum for grid clSetKernelArg(openCLKernels.prefixSumKernel, 2, sizeof(cl_uint), (void*)&gridElements); int pingpong = 0; for(cl_int offset = 1; offset <= gridElements; offset *= 2) { if(offset == 1) { clSetKernelArg(openCLKernels.prefixSumKernel, 0, sizeof(cl_mem), (void*)&particles.gridSizeBuffer); } else { clSetKernelArg(openCLKernels.prefixSumKernel, 0, sizeof(cl_mem), (void*)&(pingpong == 0 ? particles.gridBuffer[0] : particles.gridBuffer[1])); } clSetKernelArg(openCLKernels.prefixSumKernel, 1, sizeof(cl_mem), (void*)&(pingpong == 0 ? particles.gridBuffer[1] : particles.gridBuffer[0])); clSetKernelArg(openCLKernels.prefixSumKernel, 3, sizeof(cl_int), (void*)&offset); clRunKernel(openCLKernels.prefixSumKernel, gridWorkSize, workgroupSize); pingpong = 1 - pingpong; } // Reorganize particles clSetKernelArg(openCLKernels.gridReorderKernel, 0, sizeof(cl_mem), &particles.particleBuffer[particles.currentBuffer]); clSetKernelArg(openCLKernels.gridReorderKernel, 1, sizeof(cl_mem), &particles.particleBuffer[1 - particles.currentBuffer]); clSetKernelArg(openCLKernels.gridReorderKernel, 2, sizeof(cl_mem), &particles.velocityBuffer[particles.currentBuffer]); clSetKernelArg(openCLKernels.gridReorderKernel, 3, sizeof(cl_mem), &particles.velocityBuffer[1 - particles.currentBuffer]); clSetKernelArg(openCLKernels.gridReorderKernel, 4, sizeof(cl_mem), &particles.offsetBuffer); clSetKernelArg(openCLKernels.gridReorderKernel, 5, sizeof(cl_mem), (void*)&particles.gridSizeBuffer); clSetKernelArg(openCLKernels.gridReorderKernel, 6, sizeof(cl_mem), (void*)&(pingpong == 0 ? particles.gridBuffer[0] : particles.gridBuffer[1])); clSetKernelArg(openCLKernels.gridReorderKernel, 7, sizeof(cl_int), &numParticles); clRunKernel(openCLKernels.gridReorderKernel, workSize, workgroupSize); particle* testData = (particle*)malloc(sizeof(cl_float) * numParticles * 4); // Swap particle buffers particles.currentBuffer = 1 - particles.currentBuffer; // Send new cell select buffer int cellSelect[27]; for(int i = 0; i < 27; i++) { cellSelect[i] = i; } shuffle(cellSelect, 27); clEnqueueWriteBuffer(clCommandQueue(), particles.cellSelectBuffer, true, 0, 27 * sizeof(cl_int), cellSelect, 0, 0, 0); clFinish(clCommandQueue()); // Recalculate densities and normalized pressure derivatives clSetKernelArg(openCLKernels.dataKernel, 0, sizeof(cl_mem), &particles.particleBuffer[particles.currentBuffer]); clSetKernelArg(openCLKernels.dataKernel, 1, sizeof(cl_mem), &particles.dataBuffer); clSetKernelArg(openCLKernels.dataKernel, 2, sizeof(cl_mem), (void*)&particles.gridSizeBuffer); clSetKernelArg(openCLKernels.dataKernel, 3, sizeof(cl_mem), (void*)&(pingpong == 0 ? particles.gridBuffer[1] : particles.gridBuffer[0])); clSetKernelArg(openCLKernels.dataKernel, 4, sizeof(cl_mem), (void*)&particles.cellSelectBuffer); clSetKernelArg(openCLKernels.dataKernel, 5, sizeof(cl_int), &numParticles); clRunKernel(openCLKernels.dataKernel, workSize, workgroupSize); // Send new cell select buffer cellSelect[27]; for(int i = 0; i < 27; i++) { cellSelect[i] = i; } shuffle(cellSelect, 27); clEnqueueWriteBuffer(clCommandQueue(), particles.cellSelectBuffer, true, 0, 27 * sizeof(cl_int), cellSelect, 0, 0, 0); clFinish(clCommandQueue()); // Integrate position float dT = timeStep; clSetKernelArg(openCLKernels.simulationKernel, 0, sizeof(cl_mem), &particles.particleBuffer[particles.currentBuffer]); clSetKernelArg(openCLKernels.simulationKernel, 1, sizeof(cl_mem), &particles.particleBuffer[1 - particles.currentBuffer]); clSetKernelArg(openCLKernels.simulationKernel, 2, sizeof(cl_mem), &particles.velocityBuffer[particles.currentBuffer]); clSetKernelArg(openCLKernels.simulationKernel, 3, sizeof(cl_mem), &particles.velocityBuffer[1 - particles.currentBuffer]); clSetKernelArg(openCLKernels.simulationKernel, 4, sizeof(cl_mem), &particles.dataBuffer); clSetKernelArg(openCLKernels.simulationKernel, 5, sizeof(cl_mem), (void*)&particles.gridSizeBuffer); clSetKernelArg(openCLKernels.simulationKernel, 6, sizeof(cl_mem), (void*)&(pingpong == 0 ? particles.gridBuffer[1] : particles.gridBuffer[0])); clSetKernelArg(openCLKernels.simulationKernel, 7, sizeof(cl_mem), (void*)&particles.cellSelectBuffer); clSetKernelArg(openCLKernels.simulationKernel, 8, sizeof(cl_float), &dT); clSetKernelArg(openCLKernels.simulationKernel, 9, sizeof(cl_float), &time); clSetKernelArg(openCLKernels.simulationKernel, 10, sizeof(cl_int), &numParticles); clSetKernelArg(openCLKernels.simulationKernel, 11, sizeof(cl_mem), &particles.terrainBuffer); PaddedVector windDir = PadVector( TransformVector(YAxisRotationMatrix(particles.windAngle), MakeVector(1.0f, 0.0f, 0.0f)) ); clSetKernelArg(openCLKernels.simulationKernel, 12, sizeof(cl_float) * 4, &windDir); clSetKernelArg(openCLKernels.simulationKernel, 13, sizeof(cl_float), &particles.windPower); clRunKernel(openCLKernels.simulationKernel, workSize, workgroupSize); // Release buffers back to OpenGL releaseGLBuffer(particles.particleBuffer[particles.currentBuffer]); releaseGLBuffer(particles.particleBuffer[1 - particles.currentBuffer]); // Swap particle buffers particles.currentBuffer = 1 - particles.currentBuffer; //////////////////////// PART 2: RENDERIING //////////////////////////////// // Clear everything first thing. glClearColor(0.0f, 0.0f, 0.0f, 1.0f); glBindFramebuffer(GL_FRAMEBUFFER, framebuffers.backgroundFBO); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Activate shader. glUseProgram(objectShader.shaderProgram); // Set projection Matrix projection = PerspectiveMatrix( 45.0f, (float)WINDOW_WIDTH/(float)WINDOW_HEIGHT, 0.01f, 100.0f ); MatrixAsUniform(objectShader.projectionMatrix, projection); // Vertices glBindBuffer(GL_ARRAY_BUFFER, terrain.vertexBuffer); glVertexAttribPointer( objectShader.vertexPosition, 4, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 4, (void*)0 ); glEnableVertexAttribArray(objectShader.vertexPosition); // Set modelview according to camera Matrix rot = lookatMatrix(camera.pos, VectorAdd(camera.pos, camera.front), camera.up); rot = MatrixMul(RotationMatrix(camera.elevation, MakeVector(1, 0, 0)), rot); Matrix trans = TranslationMatrix(-camera.pos.x, -camera.pos.y, -camera.pos.z); Matrix modelview = MatrixMul(rot, trans); MatrixAsUniform(objectShader.modelviewMatrix, modelview); // Normal view matrix - inverse transpose of modelview. Matrix normalview = MatrixTranspose(FastMatrixInverse(modelview)); MatrixAsUniform(objectShader.normalviewMatrix, normalview); // Set heightmap texture glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, terrain.heightTexture ); glUniform1i(objectShader.terrainTexture, 0); // Set color textures glActiveTexture(GL_TEXTURE1); glBindTexture(GL_TEXTURE_2D, terrain.lowTexture); glUniform1i(objectShader.lowTexture, 1); glActiveTexture(GL_TEXTURE2); glBindTexture(GL_TEXTURE_2D, terrain.highTexture); glUniform1i(objectShader.highTexture, 2); // Turn off culling glDisable(GL_CULL_FACE); // Send element buffer to GPU and draw. glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, terrain.elementBuffer); glDrawElements( GL_TRIANGLES, 512 * 512 * 6, GL_UNSIGNED_INT, (void*)0 ); // Turn culling back on glEnable(GL_CULL_FACE); // Switch to low-res viewport glViewport(0, 0, WINDOW_WIDTH / RESOLUTION_DIVIDER, WINDOW_HEIGHT / RESOLUTION_DIVIDER); // Low-res projection matrix Matrix projectionLowres = PerspectiveMatrix( 45.0f, (float)(WINDOW_WIDTH / RESOLUTION_DIVIDER) / (float)(WINDOW_HEIGHT / RESOLUTION_DIVIDER), 0.01f, 100.0f ); // Activate particle depth FBO glClearColor(0.0f, 0.0f, 0.0f, 0.0f); glBindFramebuffer(GL_FRAMEBUFFER, framebuffers.particleFBO[0]); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Activate shader glUseProgram(particleShader.shaderProgram); // Set textures glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, framebuffers.backgroundTexture); glUniform1i(particleShader.terrainTexture, 0); // Send uniforms MatrixAsUniform(particleShader.modelviewMatrix, modelview); MatrixAsUniform(particleShader.projectionMatrix, projectionLowres); glUniform2f(particleShader.screenSize, WINDOW_WIDTH / RESOLUTION_DIVIDER, WINDOW_HEIGHT / RESOLUTION_DIVIDER); // Bind new buffer and set up arrtibutes glBindBuffer(GL_ARRAY_BUFFER, particles.vertexBuffer[particles.currentBuffer]); glVertexAttribPointer( particleShader.vertexPosition, 4, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 4, (void*)0 ); glEnableVertexAttribArray(particleShader.vertexPosition); // Bind element buffer and draw particles glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, particles.elementBuffer); glDrawElements( GL_POINTS, NUM_PARTICLES, GL_UNSIGNED_INT, (void*)0 ); // Activate particle thickness FBO glBindFramebuffer(GL_FRAMEBUFFER, framebuffers.particleThicknessFBO[0]); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Activate shader glUseProgram(particleThicknessShader.shaderProgram); // Send uniforms MatrixAsUniform(particleThicknessShader.modelviewMatrix, modelview); MatrixAsUniform(particleThicknessShader.projectionMatrix, projectionLowres); glUniform2f(particleThicknessShader.screenSize, WINDOW_WIDTH / RESOLUTION_DIVIDER, WINDOW_HEIGHT / RESOLUTION_DIVIDER); // Set textures glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, framebuffers.backgroundTexture); glUniform1i(particleThicknessShader.terrainTexture, 0); // Bind new buffer and set up arrtibutes glBindBuffer(GL_ARRAY_BUFFER, particles.vertexBuffer[particles.currentBuffer]); glVertexAttribPointer( particleThicknessShader.vertexPosition, 4, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 4, (void*)0 ); glEnableVertexAttribArray(particleThicknessShader.vertexPosition); // Enable additive blending and disable depth test glEnable(GL_BLEND); glBlendFunc(GL_ONE, GL_ONE); glDisable(GL_DEPTH_TEST); // Bind element buffer and draw particles, this time rendering thickness map glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, particles.elementBuffer); glDrawElements( GL_POINTS, NUM_PARTICLES, GL_UNSIGNED_INT, (void*)0 ); // Turn blending back off and depth test back on glDisable(GL_BLEND); glEnable(GL_DEPTH_TEST); // Activate particle velocity FBO glBindFramebuffer(GL_FRAMEBUFFER, framebuffers.velocityFBO); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Activate shader glUseProgram(particleVelocityShader.shaderProgram); // Send uniforms MatrixAsUniform(particleVelocityShader.modelviewMatrix, modelview); MatrixAsUniform(particleVelocityShader.projectionMatrix, projectionLowres); glUniform2f(particleVelocityShader.screenSize, WINDOW_WIDTH / RESOLUTION_DIVIDER, WINDOW_HEIGHT / RESOLUTION_DIVIDER); // Bind new buffer and set up arrtibutes glBindBuffer(GL_ARRAY_BUFFER, particles.vertexBuffer[particles.currentBuffer]); glVertexAttribPointer( particleVelocityShader.vertexPosition, 4, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 4, (void*)0 ); glEnableVertexAttribArray(particleVelocityShader.vertexPosition); // Bind element buffer and draw particles, this time rendering velocity map glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, particles.elementBuffer); glDrawElements( GL_POINTS, NUM_PARTICLES, GL_UNSIGNED_INT, (void*)0 ); // Curvature flow smoothing begins glUseProgram(curvatureFlowShader.shaderProgram); // Send uniforms glUniform1i(curvatureFlowShader.particleTexture, 0); glUniform2f(curvatureFlowShader.screenSize, WINDOW_WIDTH / RESOLUTION_DIVIDER, WINDOW_HEIGHT / RESOLUTION_DIVIDER); MatrixAsUniform(curvatureFlowShader.projectionMatrix, projectionLowres); // Prepare state glActiveTexture(GL_TEXTURE0); glBindBuffer(GL_ARRAY_BUFFER, screenQuad.vertexBuffer); glVertexAttribPointer( curvatureFlowShader.vertexPosition, 3, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 3, (void*)0 ); glEnableVertexAttribArray(curvatureFlowShader.vertexPosition); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, screenQuad.elementBuffer); // Smoothing loop glDisable(GL_DEPTH_TEST); pingpong = 0; for(int i = 0; i < smoothingIterations; i++) { // Bind no FBO glBindFramebuffer(GL_FRAMEBUFFER, 0); // Bind texture glBindTexture(GL_TEXTURE_2D, framebuffers.particleTexture[pingpong]); // Activate proper FBO and clear glBindFramebuffer(GL_FRAMEBUFFER, framebuffers.particleFBO[1 - pingpong]); // Draw a quad glDrawElements( GL_TRIANGLES, 6, GL_UNSIGNED_INT, (void*)0 ); // Switch buffers pingpong = 1 - pingpong; } glEnable(GL_DEPTH_TEST); // Activate particle color FBO glBindFramebuffer(GL_FRAMEBUFFER, framebuffers.particleColorFBO); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Liquid shading shader glUseProgram(liquidShadeShader.shaderProgram); // Bind and set textures glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, framebuffers.particleTexture[0]); glUniform1i(liquidShadeShader.particleTexture, 0); glActiveTexture(GL_TEXTURE1); glBindTexture(GL_TEXTURE_2D, framebuffers.particleThicknessTexture[0]); glUniform1i(liquidShadeShader.particleThicknessTexture, 1); glActiveTexture(GL_TEXTURE2); glBindTexture(GL_TEXTURE_2D, terrain.envTexture); glUniform1i(liquidShadeShader.environmentTexture, 2); glActiveTexture(GL_TEXTURE3); glBindTexture(GL_TEXTURE_2D, framebuffers.particleVelocityTexture); glUniform1i(liquidShadeShader.velocityTexture, 3); // Send uniforms glUniform2f(liquidShadeShader.screenSize, WINDOW_WIDTH, WINDOW_HEIGHT); MatrixAsUniform(liquidShadeShader.modelviewMatrix, modelview); MatrixAsUniform(liquidShadeShader.projectionMatrix, projection); glUniform1i(liquidShadeShader.useThickness, useThickness); // Draw a quad glDisable(GL_DEPTH_TEST); glBindBuffer(GL_ARRAY_BUFFER, screenQuad.vertexBuffer); glVertexAttribPointer( liquidShadeShader.vertexPosition, 3, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 3, (void*)0 ); glEnableVertexAttribArray(liquidShadeShader.vertexPosition); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, screenQuad.elementBuffer); glDrawElements( GL_TRIANGLES, 6, GL_UNSIGNED_INT, (void*)0 ); glEnable(GL_DEPTH_TEST); // Switch back to full-res viewport glViewport(0, 0, WINDOW_WIDTH, WINDOW_HEIGHT); // Deactivate FBOs glBindFramebuffer(GL_FRAMEBUFFER, 0); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Compose shader glUseProgram(compositionShader.shaderProgram); // Bind and set textures glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, terrain.envTexture); glUniform1i(compositionShader.backgroundTexture, 0); glActiveTexture(GL_TEXTURE1); glBindTexture(GL_TEXTURE_2D, framebuffers.particleColorTexture); glUniform1i(compositionShader.particleTexture, 1); glActiveTexture(GL_TEXTURE2); glBindTexture(GL_TEXTURE_2D, framebuffers.backgroundTexture); glUniform1i(compositionShader.terrainTexture, 2); // Send uniforms MatrixAsUniform(compositionShader.modelviewMatrix, modelview); // Draw a quad glDisable(GL_DEPTH_TEST); glBindBuffer(GL_ARRAY_BUFFER, screenQuad.vertexBuffer); glVertexAttribPointer( compositionShader.vertexPosition, 3, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 3, (void*)0 ); glEnableVertexAttribArray(compositionShader.vertexPosition); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, screenQuad.elementBuffer); glDrawElements( GL_TRIANGLES, 6, GL_UNSIGNED_INT, (void*)0 ); glEnable(GL_DEPTH_TEST); // Switch drawing area and displayed area. glutSwapBuffers(); }
int main (int argc, char *argv[]) { int numtasks, /* number of tasks in partition */ taskid, /* a task identifier */ numworkers, /* number of worker tasks */ source, /* task id of message source */ dest, /* task id of message destination */ mtype, /* message type */ rows, /* rows of matrix A sent to each worker */ averow, extra, offset, /* used to determine rows sent to each worker */ i, j, k, /* variables for loops */ errorCode = 1; /* error code initialized for MPI_Abort */ float a[ROW_A][COL_A], /* matrix A for multiplication */ b[COL_A][COL_B], /* matrix B for multiplication */ c[ROW_A][COL_B]; /* result matrix C */ MPI_Status status; /* the status for receiving the result */ /*Initializing MPI execution environment*/ MPI_Init(&argc,&argv); MPI_Comm_rank(MPI_COMM_WORLD, &taskid); MPI_Comm_size(MPI_COMM_WORLD, &numtasks); if (numtasks < 2 ) { printf("Need at least two MPI tasks. Quitting...\n"); MPI_Abort(MPI_COMM_WORLD, 0); exit(1); } numworkers = numtasks-1; /* number of workers */ /**************************** master task ************************************/ if (taskid == MASTER) { /* Initializing both matrices on master node */ for (i = 0; i < ROW_A; i++) for (j = 0; j < COL_A; j++) // change here to use random integer a[i][j]= 1; for (i = 0; i < COL_A; i++) for (j = 0; j < COL_B; j++) // change here to use random integer b[i][j]= 1; /* Computing the average row and extra row for each process */ averow = ROW_A/numworkers; extra = ROW_A%numworkers; offset = 0; mtype = FROM_MASTER; /* Distributing the task to each worker */ for (dest = 1; dest <= numworkers; dest++) { rows = (dest <= extra) ? averow+1 : averow; printf("Sending %d rows to task %d offset = %d\n", rows, dest, offset); MPI_Send(&offset, 1, MPI_INT, dest, mtype, MPI_COMM_WORLD); MPI_Send(&rows, 1, MPI_INT, dest, mtype, MPI_COMM_WORLD); MPI_Send(&a[offset][0], rows*COL_A, MPI_FLOAT, dest, mtype, MPI_COMM_WORLD); MPI_Send(&b, COL_A*COL_B, MPI_FLOAT, dest, mtype, MPI_COMM_WORLD); offset = offset + rows; } /* Receive results from worker tasks */ mtype = FROM_WORKER; for (i = 1; i <= numworkers; i++) { source = i; MPI_Recv(&offset, 1, MPI_INT, source, mtype, MPI_COMM_WORLD, &status); MPI_Recv(&rows, 1, MPI_INT, source, mtype, MPI_COMM_WORLD, &status); MPI_Recv(&c[offset][0], rows*COL_B, MPI_FLOAT, source, mtype, MPI_COMM_WORLD, &status); printf("Received results from task %d\n",source); } /* Master prints results */ printf("******************************************************\n"); printf("Result Matrix:\n"); for (i = 0; i < ROW_A; i++) { printf("\n"); for (j = 0; j < COL_B; j++) printf("%6.2f ", c[i][j]); } printf("\n******************************************************\n"); printf ("Done.\n"); } /**************************** worker task ************************************/ if (taskid > MASTER) { /* Each receives task from master*/ mtype = FROM_MASTER; MPI_Recv(&offset, 1, MPI_INT, MASTER, mtype, MPI_COMM_WORLD, &status); MPI_Recv(&rows, 1, MPI_INT, MASTER, mtype, MPI_COMM_WORLD, &status); MPI_Recv(&a, rows*COL_A, MPI_FLOAT, MASTER, mtype, MPI_COMM_WORLD, &status); MPI_Recv(&b, COL_A*COL_B, MPI_FLOAT, MASTER, mtype, MPI_COMM_WORLD, &status); /* Calling function from CUDA. Each worker computes on their GPU */ MatrixMul(*a, *b, *c, WIDTH, 128); /* Each worker sends result back to the master */ mtype = FROM_WORKER; MPI_Send(&offset, 1, MPI_INT, MASTER, mtype, MPI_COMM_WORLD); MPI_Send(&rows, 1, MPI_INT, MASTER, mtype, MPI_COMM_WORLD); MPI_Send(&c, rows*COL_B, MPI_FLOAT, MASTER, mtype, MPI_COMM_WORLD); } /* Terminate MPI execution environment */ MPI_Finalize(); }
A3DMatrix& A3DMatrix::operator *= (const A3DMatrix& mat) { MatrixMul(*this, *this, mat, 4); Normalise(); return *this; }
int main(void) { char mStr[1024]; matrix *ans, *m1, *m2; int sc = 0; printf("Which operation: "); char op = tolower(getchar()); while(op != '+' || op != '-' || op != '*' || op != '/' || op != 'i') { puts(opErr); op = tolower(getchar()); } printf("First matrix:\n"); scanf("%s", mStr); m1 = MatrixInit(mStr); MatrixPrint(m1); if(op == 'a' || op == 's' || op == 'm') { printf("Second matrix:\n"); scanf("%s", mStr); m2 = MatrixInit(mStr); MatrixPrint(m2); } else if(op == 'c') { printf("Scalar multiple:\n"); scanf("%d", &sc); } switch(op) { case 'a': ans = MatrixAdd(m1, m2); break; case 's': ans = MatrixSub(m1, m2); break; case 'm': ans = MatrixMul(m1, m2); break; case 'i': ans = MatrixInv(m1); break; case 'c': ans = MatrixSMul(m1, sc); break; default: printf("Something went very wrong.\n"); return 1; } printf("Answer:\n"); MatrixPrint(ans); MatrixFree(m1); MatrixFree(ans); if(op == 'a' || op == 's' || op == 'm') { MatrixFree(m2); } return 0; }