void VSMathLib::matrixToGL(ComputedMatrixTypes aType) { if (mInit) { if (mBlocks) { if (aType == NORMAL && mComputedMatUniformName[NORMAL] != "") { computeNormalMatrix(); if (mComputedMatUniformArrayIndex[NORMAL]) VSShaderLib::setBlockUniformArrayElement(mBlockName, mComputedMatUniformName[NORMAL], mComputedMatUniformArrayIndex[NORMAL], mNormal); else VSShaderLib::setBlockUniform(mBlockName, mComputedMatUniformName[NORMAL], mNormal); } else if (mComputedMatUniformName[aType] != "") { computeDerivedMatrix(aType); if (mComputedMatUniformArrayIndex[aType]) VSShaderLib::setBlockUniformArrayElement(mBlockName, mComputedMatUniformName[aType], mComputedMatUniformArrayIndex[aType], mCompMatrix[aType]); else VSShaderLib::setBlockUniform(mBlockName, mComputedMatUniformName[aType], mCompMatrix[aType]); } } } else { int p,loc; if (mUniformName[aType] != "") { glGetIntegerv(GL_CURRENT_PROGRAM,&p); loc = glGetUniformLocation(p, mUniformName[aType].c_str()); if (aType == NORMAL && mComputedMatUniformName[NORMAL] != "") { computeNormalMatrix3x3(); loc = glGetUniformLocation(p, mComputedMatUniformName[NORMAL].c_str()); glProgramUniformMatrix3fv(p, loc, 1, false, mNormal3x3); } else if (mComputedMatUniformName[aType] != "") { computeDerivedMatrix(aType); loc = glGetUniformLocation(p, mComputedMatUniformName[aType].c_str()); glProgramUniformMatrix4fv(p, loc, 1, false, mCompMatrix[aType]); } } } }
// Compute res = M * point void VSMathLib::multMatrixPoint(ComputedMatrixTypes aType, float *point, float *res) { if (aType == NORMAL) { computeNormalMatrix(); for (int i = 0; i < 3; ++i) { res[i] = 0.0f; for (int j = 0; j < 3; j++) { res[i] += point[j] * mNormal[j*4 + i]; } } } else { computeDerivedMatrix(aType); for (int i = 0; i < 4; ++i) { res[i] = 0.0f; for (int j = 0; j < 4; j++) { res[i] += point[j] * mCompMatrix[aType][j*4 + i]; } } } }
void GameOver::draw(struct MyMesh* mesh, VSShaderLib& shader, GLint& pvm_uniformId, GLint& vm_uniformId, GLint& normal_uniformId, GLint& texMode_uniformId, int *objId){ *objId=11; GLint loc; // send the material loc = glGetUniformLocation(shader.getProgramIndex(), "mat.ambient"); glUniform4fv(loc, 1, mesh[*objId].mat.ambient); loc = glGetUniformLocation(shader.getProgramIndex(), "mat.diffuse"); glUniform4fv(loc, 1, mesh[*objId].mat.diffuse); loc = glGetUniformLocation(shader.getProgramIndex(), "mat.specular"); glUniform4fv(loc, 1, mesh[*objId].mat.specular); loc = glGetUniformLocation(shader.getProgramIndex(), "mat.shininess"); glUniform1f(loc,mesh[*objId].mat.shininess); pushMatrix(MODEL); translate(MODEL, -7.5f, 0.0f, 15.0f); scale(MODEL, 15.0f, 0.0f, 30.0f); rotate(MODEL, 90.0, 0.0f, 0.0f, 1.0f); rotate(MODEL, 180.0, 1.0f, 0.0f, 0.0f); // send matrices to OGL computeDerivedMatrix(PROJ_VIEW_MODEL); glUniformMatrix4fv(vm_uniformId, 1, GL_FALSE, mCompMatrix[VIEW_MODEL]); glUniformMatrix4fv(pvm_uniformId, 1, GL_FALSE, mCompMatrix[PROJ_VIEW_MODEL]); computeNormalMatrix3x3(); glUniformMatrix3fv(normal_uniformId, 1, GL_FALSE, mNormal3x3); // Render mesh glUniform1i(texMode_uniformId, 4); // apenas o texel glBindVertexArray(mesh[*objId].vao); glDrawElements(mesh[*objId].type,mesh[*objId].numIndexes, GL_UNSIGNED_INT, 0); glBindVertexArray(0); popMatrix(MODEL); }
void Particles::render(GLint texture, struct MyMesh mesh, GLint pvm_uniformId, GLint vm_uniformId, GLint normal_uniformId, VSShaderLib shader, float angle) { float particle_color[4]; // draw fireworks particles glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, texture); glActiveTexture(GL_TEXTURE1); glBindTexture(GL_TEXTURE_2D, texture); glDisable(GL_DEPTH_TEST); /* não interessa o z-buffer: as partículas podem ser desenhadas umas por cima das outras sem problemas de ordenação */ glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE); for (int i = 0; i < MAX_PARTICULAS; i++) { if (particula[i].life > 0.0f) /* só desenha as que ainda estão vivas */ { /* A vida da partícula representa o canal alpha da cor. Como o blend está activo a cor final é a soma da cor rgb do fragmento multiplicada pelo alpha com a cor do pixel destino */ particle_color[0] = particula[i].r; particle_color[1] = particula[i].g; particle_color[2] = particula[i].b; particle_color[3] = particula[i].life; // send the material - diffuse color modulated with texture GLint loc = glGetUniformLocation(shader.getProgramIndex(), "mat.diffuse"); glUniform4fv(loc, 1, particle_color); pushMatrix(MODEL); translate(MODEL, particula[i].x, particula[i].y, particula[i].z); rotate(MODEL, angle, 0, 1, 0); scale(MODEL, 0.3, 0.3, 0.3); //rotate(MODEL, 180, 0, 0, 1); // send matrices to OGL computeDerivedMatrix(PROJ_VIEW_MODEL); glUniformMatrix4fv(vm_uniformId, 1, GL_FALSE, mCompMatrix[VIEW_MODEL]); glUniformMatrix4fv(pvm_uniformId, 1, GL_FALSE, mCompMatrix[PROJ_VIEW_MODEL]); computeNormalMatrix3x3(); glUniformMatrix3fv(normal_uniformId, 1, GL_FALSE, mNormal3x3); glBindVertexArray(mesh.vao); glDrawElements(mesh.type, mesh.numIndexes, GL_UNSIGNED_INT, 0); popMatrix(MODEL); } } glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glBindVertexArray(0); glBindTexture(GL_TEXTURE_2D, 0); glEnable(GL_DEPTH_TEST); }
// returns a pointer to the requested matrix float * VSMathLib::get(ComputedMatrixTypes aType) { switch (aType) { case NORMAL: computeNormalMatrix3x3(); return mNormal3x3; break; default: computeDerivedMatrix(aType); return mCompMatrix[aType]; break; } // this should never happen! return NULL; }
void HudMessage::render(VSShaderLib &shader, GLint &pvm_uniformId, GLint &vm_uniformId, GLint &normal_uniformId, GLint &texMode_uniformId) { GLuint loc; for (int i = 0; i < meshLength; ++i) { if (mesh[i].mat.texCount != 0) { glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, mesh[i].texUnits[messageType]); glUniform1i(texMode_uniformId, 2); } for (int j = 0; j < mesh[i].vaoElements; j++) { // send the material loc = glGetUniformLocation(shader.getProgramIndex(), "mat.ambient"); glUniform4fv(loc, 1, mesh[i].mat.ambient); loc = glGetUniformLocation(shader.getProgramIndex(), "mat.diffuse"); glUniform4fv(loc, 1, mesh[i].mat.diffuse); loc = glGetUniformLocation(shader.getProgramIndex(), "mat.specular"); glUniform4fv(loc, 1, mesh[i].mat.specular); loc = glGetUniformLocation(shader.getProgramIndex(), "mat.shininess"); glUniform1f(loc, mesh[i].mat.shininess); pushMatrix(MODEL); translate(MODEL, current_position[0], current_position[1], current_position[2]); if (i == 0) { scale(MODEL, 4.0f, 4.0f, 0.0f); } // send matrices to OGL computeDerivedMatrix(PROJ_VIEW_MODEL); glUniformMatrix4fv(vm_uniformId, 1, GL_FALSE, mCompMatrix[VIEW_MODEL]); glUniformMatrix4fv(pvm_uniformId, 1, GL_FALSE, mCompMatrix[PROJ_VIEW_MODEL]); computeNormalMatrix3x3(); glUniformMatrix3fv(normal_uniformId, 1, GL_FALSE, mNormal3x3); // Render mesh glBindVertexArray(mesh[i].vao); glDrawElements(mesh[i].type, mesh[i].numIndexes, GL_UNSIGNED_INT, 0); glBindVertexArray(0); popMatrix(MODEL); } glUniform1i(texMode_uniformId, 0); } glBindTexture(GL_TEXTURE_2D, 0); }
// computes the derived normal matrix void VSMathLib::computeNormalMatrix() { computeDerivedMatrix(VIEW_MODEL); mMat3x3[0] = mCompMatrix[VIEW_MODEL][0]; mMat3x3[1] = mCompMatrix[VIEW_MODEL][1]; mMat3x3[2] = mCompMatrix[VIEW_MODEL][2]; mMat3x3[3] = mCompMatrix[VIEW_MODEL][4]; mMat3x3[4] = mCompMatrix[VIEW_MODEL][5]; mMat3x3[5] = mCompMatrix[VIEW_MODEL][6]; mMat3x3[6] = mCompMatrix[VIEW_MODEL][8]; mMat3x3[7] = mCompMatrix[VIEW_MODEL][9]; mMat3x3[8] = mCompMatrix[VIEW_MODEL][10]; float det, invDet; det = mMat3x3[0] * (mMat3x3[4] * mMat3x3[8] - mMat3x3[5] * mMat3x3[7]) + mMat3x3[1] * (mMat3x3[5] * mMat3x3[6] - mMat3x3[8] * mMat3x3[3]) + mMat3x3[2] * (mMat3x3[3] * mMat3x3[7] - mMat3x3[4] * mMat3x3[6]); invDet = 1.0f/det; mNormal[0] = (mMat3x3[4] * mMat3x3[8] - mMat3x3[5] * mMat3x3[7]) * invDet; mNormal[1] = (mMat3x3[5] * mMat3x3[6] - mMat3x3[8] * mMat3x3[3]) * invDet; mNormal[2] = (mMat3x3[3] * mMat3x3[7] - mMat3x3[4] * mMat3x3[6]) * invDet; mNormal[3] = 0.0f; mNormal[4] = (mMat3x3[2] * mMat3x3[7] - mMat3x3[1] * mMat3x3[8]) * invDet; mNormal[5] = (mMat3x3[0] * mMat3x3[8] - mMat3x3[2] * mMat3x3[6]) * invDet; mNormal[6] = (mMat3x3[1] * mMat3x3[6] - mMat3x3[7] * mMat3x3[0]) * invDet; mNormal[7] = 0.0f; mNormal[8] = (mMat3x3[1] * mMat3x3[5] - mMat3x3[4] * mMat3x3[2]) * invDet; mNormal[9] = (mMat3x3[2] * mMat3x3[3] - mMat3x3[0] * mMat3x3[5]) * invDet; mNormal[10] =(mMat3x3[0] * mMat3x3[4] - mMat3x3[3] * mMat3x3[1]) * invDet; mNormal[11] = 0.0; }
// Sends all matrices whose respectived uniforms have been named void VSMathLib::matricesToGL() { if (mInit) { if (mBlocks) { for (int i = 0 ; i < COUNT_MATRICES; ++i ) { if (mUniformName[i] != "") if (mUniformArrayIndex[i]) VSShaderLib::setBlockUniformArrayElement(mBlockName, mUniformName[i], mUniformArrayIndex[i], mMatrix[i]); else VSShaderLib::setBlockUniform(mBlockName, mUniformName[i], mMatrix[i]); } if (mComputedMatUniformName[NORMAL] != "") { computeNormalMatrix(); if (mComputedMatUniformArrayIndex[NORMAL]) VSShaderLib::setBlockUniformArrayElement(mBlockName, mComputedMatUniformName[NORMAL], mComputedMatUniformArrayIndex[NORMAL], mNormal); else VSShaderLib::setBlockUniform(mBlockName, mComputedMatUniformName[NORMAL], mNormal); } for (int i = 0; i < COUNT_COMPUTED_MATRICES-1; ++i) { if (mComputedMatUniformName[i] != "") { computeDerivedMatrix((VSMathLib::ComputedMatrixTypes)i); if (mComputedMatUniformArrayIndex[i]) VSShaderLib::setBlockUniformArrayElement(mBlockName, mComputedMatUniformName[i], mComputedMatUniformArrayIndex[i], mCompMatrix[i]); else VSShaderLib::setBlockUniform(mBlockName, mComputedMatUniformName[i], mCompMatrix[i]); } } } else { int p,loc; glGetIntegerv(GL_CURRENT_PROGRAM,&p); for (int i = 0; i < COUNT_MATRICES; ++i) { if (mUniformName[i] != "") { loc = glGetUniformLocation(p, mUniformName[i].c_str()); glProgramUniformMatrix4fv(p, loc, 1, false, mMatrix[i]); } } if (mComputedMatUniformName[NORMAL] != "") { computeNormalMatrix3x3(); loc = glGetUniformLocation(p, mComputedMatUniformName[NORMAL].c_str()); glProgramUniformMatrix3fv(p, loc, 1, false, mNormal3x3); } for (int i = 0; i < COUNT_COMPUTED_MATRICES-1; ++i) { if (mComputedMatUniformName[i] != "") { computeDerivedMatrix((VSMathLib::ComputedMatrixTypes)i); loc = glGetUniformLocation(p, mComputedMatUniformName[i].c_str()); glProgramUniformMatrix4fv(p, loc, 1, false, mCompMatrix[i]); } } } } }
void Billboard::draw(struct MyMesh* mesh, VSShaderLib& shader, GLint& pvm_uniformId, GLint& vm_uniformId, GLint& normal_uniformId, GLint& texMode_uniformId, int *objId){ float modelview[16]; float pos[3]; //pos[0] = getPosX(); pos[1] = getPosY(); pos[2] = getPosZ(); float cam[3]; cam[0] = getCamX(); cam[1] = getCamY(); cam[2] = getCamZ(); GLint loc; //Draw trees billboards glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glUniform1i(texMode_uniformId, 1); // draw textured quads for(int j = 1; j < 3; j++) { pushMatrix(MODEL); translate(MODEL,-7.0,0.0,-10.0+j*5); pos[0] = -7.0; pos[1] = 0; pos[2] = -10.0+j*5; if (getType() == 2){ l3dBillboardSphericalBegin(cam,pos); } else if (getType() == 3){ l3dBillboardCylindricalBegin(cam,pos); } *objId=17; //quad for tree //diffuse and ambient color are not used in the tree quads loc = glGetUniformLocation(shader.getProgramIndex(), "mat.specular"); glUniform4fv(loc, 1, mesh[*objId].mat.specular); loc = glGetUniformLocation(shader.getProgramIndex(), "mat.shininess"); glUniform1f(loc,mesh[*objId].mat.shininess); pushMatrix(MODEL); translate(MODEL, 0.0, 3.0, 0.0f); // send matrices to OGL if (getType() == 0 || getType() == 1) { //Cheating matrix reset billboard techniques computeDerivedMatrix(VIEW_MODEL); memcpy(modelview, mCompMatrix[VIEW_MODEL], sizeof(float) * 16); //save VIEW_MODEL in modelview matrix //reset VIEW_MODEL if(getType()==0){ BillboardCheatSphericalBegin(); } else{ BillboardCheatCylindricalBegin(); } computeDerivedMatrix_PVM(); // calculate PROJ_VIEW_MODEL } else computeDerivedMatrix(PROJ_VIEW_MODEL); glUniform1i(texMode_uniformId, 13); glUniformMatrix4fv(vm_uniformId, 1, GL_FALSE, mCompMatrix[VIEW_MODEL]); glUniformMatrix4fv(pvm_uniformId, 1, GL_FALSE, mCompMatrix[PROJ_VIEW_MODEL]); computeNormalMatrix3x3(); glUniformMatrix3fv(normal_uniformId, 1, GL_FALSE, mNormal3x3); glBindVertexArray(mesh[*objId].vao); glDrawElements(mesh[*objId].type,mesh[*objId].numIndexes, GL_UNSIGNED_INT, 0); popMatrix(MODEL); popMatrix(MODEL); } glDisable(GL_BLEND); }