From bff80808b7f98aab99cb32387c26e16eb5c1fc23 Mon Sep 17 00:00:00 2001 From: Manuel Martin Date: Sun, 28 Feb 2016 20:41:22 +0100 Subject: [PATCH] Avoid double-to-float warnings in OpenGL pyramid sample See #16910. --- samples/opengl/pyramid/mathstuff.cpp | 92 ++++++++++++++-------------- samples/opengl/pyramid/mathstuff.h | 14 ++--- samples/opengl/pyramid/oglstuff.cpp | 72 ++++++++++++++-------- samples/opengl/pyramid/oglstuff.h | 16 +++-- 4 files changed, 110 insertions(+), 84 deletions(-) diff --git a/samples/opengl/pyramid/mathstuff.cpp b/samples/opengl/pyramid/mathstuff.cpp index 1cad61038a..754a99663d 100644 --- a/samples/opengl/pyramid/mathstuff.cpp +++ b/samples/opengl/pyramid/mathstuff.cpp @@ -66,68 +66,68 @@ double AngleBetween(myVec3 v1, myVec3 v2) // Matrix 4x4 by 4x1 multiplication // Attention: No bounds check! -myVec4 MyMatMul4x1(const float *m1, const myVec4& v) +myVec4 MyMatMul4x1(const double *m1, const myVec4& v) { myVec4 mmv; - mmv.x = (double) m1[0] * v.x + m1[4] * v.y + m1[8] * v.z + m1[12] * v.w ; - mmv.y = (double) m1[1] * v.x + m1[5] * v.y + m1[9] * v.z + m1[13] * v.w ; - mmv.z = (double) m1[2] * v.x + m1[6] * v.y + m1[10] * v.z + m1[14] * v.w ; - mmv.w = (double) m1[3] * v.x + m1[7] * v.y + m1[11] * v.z + m1[15] * v.w ; + mmv.x = m1[0] * v.x + m1[4] * v.y + m1[8] * v.z + m1[12] * v.w ; + mmv.y = m1[1] * v.x + m1[5] * v.y + m1[9] * v.z + m1[13] * v.w ; + mmv.z = m1[2] * v.x + m1[6] * v.y + m1[10] * v.z + m1[14] * v.w ; + mmv.w = m1[3] * v.x + m1[7] * v.y + m1[11] * v.z + m1[15] * v.w ; return mmv; } // Matrix 4x4 multiplication // Attention: No bounds check! -void MyMatMul4x4(const float *m1, const float *m2, float* mm) +void MyMatMul4x4(const double *m1, const double *m2, double* mm) { - mm[0] = (double) m1[0] * m2[0] + m1[4] * m2[1] + m1[8] * m2[2] + m1[12] * m2[3] ; - mm[1] = (double) m1[1] * m2[0] + m1[5] * m2[1] + m1[9] * m2[2] + m1[13] * m2[3] ; - mm[2] = (double) m1[2] * m2[0] + m1[6] * m2[1] + m1[10] * m2[2] + m1[14] * m2[3] ; - mm[3] = (double) m1[3] * m2[0] + m1[7] * m2[1] + m1[11] * m2[2] + m1[15] * m2[3] ; - mm[4] = (double) m1[0] * m2[4] + m1[4] * m2[5] + m1[8] * m2[6] + m1[12] * m2[7] ; - mm[5] = (double) m1[1] * m2[4] + m1[5] * m2[5] + m1[9] * m2[6] + m1[13] * m2[7] ; - mm[6] = (double) m1[2] * m2[4] + m1[6] * m2[5] + m1[10] * m2[6] + m1[14] * m2[7] ; - mm[7] = (double) m1[3] * m2[4] + m1[7] * m2[5] + m1[11] * m2[6] + m1[15] * m2[7] ; - mm[8] = (double) m1[0] * m2[8] + m1[4] * m2[9] + m1[8] * m2[10] + m1[12] * m2[11] ; - mm[9] = (double) m1[1] * m2[8] + m1[5] * m2[9] + m1[9] * m2[10] + m1[13] * m2[11] ; - mm[10] = (double) m1[2] * m2[8] + m1[6] * m2[9] + m1[10] * m2[10] + m1[14] * m2[11] ; - mm[11] = (double) m1[3] * m2[8] + m1[7] * m2[9] + m1[11] * m2[10] + m1[15] * m2[11] ; - mm[12] = (double) m1[0] * m2[12] + m1[4] * m2[13] + m1[8] * m2[14] + m1[12] * m2[15] ; - mm[13] = (double) m1[1] * m2[12] + m1[5] * m2[13] + m1[9] * m2[14] + m1[13] * m2[15] ; - mm[14] = (double) m1[2] * m2[12] + m1[6] * m2[13] + m1[10] * m2[14] + m1[14] * m2[15] ; - mm[15] = (double) m1[3] * m2[12] + m1[7] * m2[13] + m1[11] * m2[14] + m1[15] * m2[15] ; + mm[0] = m1[0] * m2[0] + m1[4] * m2[1] + m1[8] * m2[2] + m1[12] * m2[3] ; + mm[1] = m1[1] * m2[0] + m1[5] * m2[1] + m1[9] * m2[2] + m1[13] * m2[3] ; + mm[2] = m1[2] * m2[0] + m1[6] * m2[1] + m1[10] * m2[2] + m1[14] * m2[3] ; + mm[3] = m1[3] * m2[0] + m1[7] * m2[1] + m1[11] * m2[2] + m1[15] * m2[3] ; + mm[4] = m1[0] * m2[4] + m1[4] * m2[5] + m1[8] * m2[6] + m1[12] * m2[7] ; + mm[5] = m1[1] * m2[4] + m1[5] * m2[5] + m1[9] * m2[6] + m1[13] * m2[7] ; + mm[6] = m1[2] * m2[4] + m1[6] * m2[5] + m1[10] * m2[6] + m1[14] * m2[7] ; + mm[7] = m1[3] * m2[4] + m1[7] * m2[5] + m1[11] * m2[6] + m1[15] * m2[7] ; + mm[8] = m1[0] * m2[8] + m1[4] * m2[9] + m1[8] * m2[10] + m1[12] * m2[11] ; + mm[9] = m1[1] * m2[8] + m1[5] * m2[9] + m1[9] * m2[10] + m1[13] * m2[11] ; + mm[10] = m1[2] * m2[8] + m1[6] * m2[9] + m1[10] * m2[10] + m1[14] * m2[11] ; + mm[11] = m1[3] * m2[8] + m1[7] * m2[9] + m1[11] * m2[10] + m1[15] * m2[11] ; + mm[12] = m1[0] * m2[12] + m1[4] * m2[13] + m1[8] * m2[14] + m1[12] * m2[15] ; + mm[13] = m1[1] * m2[12] + m1[5] * m2[13] + m1[9] * m2[14] + m1[13] * m2[15] ; + mm[14] = m1[2] * m2[12] + m1[6] * m2[13] + m1[10] * m2[14] + m1[14] * m2[15] ; + mm[15] = m1[3] * m2[12] + m1[7] * m2[13] + m1[11] * m2[14] + m1[15] * m2[15] ; } // Matrix 4x4 inverse. Returns the determinant. // Attention: No bounds check! // Method used is "adjugate matrix" with "cofactors". // A faster method, such as "LU decomposition", isn't much faster than this code. -double MyMatInverse(const float *m, float *minv) +double MyMatInverse(const double *m, double *minv) { double det; double cof[16], sdt[19]; // The 2x2 determinants used for cofactors - sdt[0] = (double) m[10] * m[15] - m[14] * m[11] ; - sdt[1] = (double) m[9] * m[15] - m[13] * m[11] ; - sdt[2] = (double) m[9] * m[14] - m[13] * m[10] ; - sdt[3] = (double) m[8] * m[15] - m[12] * m[11] ; - sdt[4] = (double) m[8] * m[14] - m[12] * m[10] ; - sdt[5] = (double) m[8] * m[13] - m[12] * m[9] ; - sdt[6] = (double) m[6] * m[15] - m[14] * m[7] ; - sdt[7] = (double) m[5] * m[15] - m[13] * m[7] ; - sdt[8] = (double) m[5] * m[14] - m[13] * m[6] ; - sdt[9] = (double) m[4] * m[15] - m[12] * m[7] ; - sdt[10] = (double) m[4] * m[14] - m[12] * m[6] ; - sdt[11] = (double) m[5] * m[15] - m[13] * m[7] ; - sdt[12] = (double) m[4] * m[13] - m[12] * m[5] ; - sdt[13] = (double) m[6] * m[11] - m[10] * m[7] ; - sdt[14] = (double) m[5] * m[11] - m[9] * m[7] ; - sdt[15] = (double) m[5] * m[10] - m[9] * m[6] ; - sdt[16] = (double) m[4] * m[11] - m[8] * m[7] ; - sdt[17] = (double) m[4] * m[10] - m[8] * m[6] ; - sdt[18] = (double) m[4] * m[9] - m[8] * m[5] ; + sdt[0] = m[10] * m[15] - m[14] * m[11] ; + sdt[1] = m[9] * m[15] - m[13] * m[11] ; + sdt[2] = m[9] * m[14] - m[13] * m[10] ; + sdt[3] = m[8] * m[15] - m[12] * m[11] ; + sdt[4] = m[8] * m[14] - m[12] * m[10] ; + sdt[5] = m[8] * m[13] - m[12] * m[9] ; + sdt[6] = m[6] * m[15] - m[14] * m[7] ; + sdt[7] = m[5] * m[15] - m[13] * m[7] ; + sdt[8] = m[5] * m[14] - m[13] * m[6] ; + sdt[9] = m[4] * m[15] - m[12] * m[7] ; + sdt[10] = m[4] * m[14] - m[12] * m[6] ; + sdt[11] = m[5] * m[15] - m[13] * m[7] ; + sdt[12] = m[4] * m[13] - m[12] * m[5] ; + sdt[13] = m[6] * m[11] - m[10] * m[7] ; + sdt[14] = m[5] * m[11] - m[9] * m[7] ; + sdt[15] = m[5] * m[10] - m[9] * m[6] ; + sdt[16] = m[4] * m[11] - m[8] * m[7] ; + sdt[17] = m[4] * m[10] - m[8] * m[6] ; + sdt[18] = m[4] * m[9] - m[8] * m[5] ; // The cofactors, transposed cof[0] = m[5] * sdt[0] - m[6] * sdt[1] + m[7] * sdt[2] ; cof[1] = - m[1] * sdt[0] + m[2] * sdt[1] - m[3] * sdt[2] ; @@ -166,7 +166,7 @@ double MyMatInverse(const float *m, float *minv) // Matrix of rotation around an axis in the origin. // angle is positive if follows axis (right-hand rule) // Attention: No bounds check! -void MyRotate(const myVec3& axis, double angle, float *mrot) +void MyRotate(const myVec3& axis, double angle, double *mrot) { double c = cos(angle); double s = sin(angle); @@ -197,7 +197,7 @@ void MyRotate(const myVec3& axis, double angle, float *mrot) // Unchecked conditions: // camPos != targ && camUp != {0,0,0} // camUo can't be parallel to camPos - targ -void MyLookAt(const myVec3& camPos, const myVec3& camUp, const myVec3& targ, float *mt) +void MyLookAt(const myVec3& camPos, const myVec3& camUp, const myVec3& targ, double *mt) { myVec3 tc = MyNormalize(targ - camPos); myVec3 up = MyNormalize(camUp); @@ -228,7 +228,7 @@ void MyLookAt(const myVec3& camPos, const myVec3& camUp, const myVec3& targ, flo // From camera coordinates to canonical (2x2x2 cube) coordinates. // Attention: No bounds check! // Unchecked conditions: fov > 0 && zNear > 0 && zFar > zNear && aspect > 0 -void MyPerspective(double fov, double aspect, double zNear, double zFar, float *mp) +void MyPerspective(double fov, double aspect, double zNear, double zFar, double *mp) { double f = 1.0 / tan(fov / 2.0); @@ -251,7 +251,7 @@ void MyPerspective(double fov, double aspect, double zNear, double zFar, float * // Attention: No bounds check! // Unchecked conditions: left != right && bottom != top && zNear != zFar void MyOrtho(double left, double right, double bottom, double top, - double zNear, double zFar, float *mo) + double zNear, double zFar, double *mo) { // Store the matrix in column order mo[0] = 2.0 / (right - left) ; diff --git a/samples/opengl/pyramid/mathstuff.h b/samples/opengl/pyramid/mathstuff.h index 98e4095c6b..538ea13210 100644 --- a/samples/opengl/pyramid/mathstuff.h +++ b/samples/opengl/pyramid/mathstuff.h @@ -59,25 +59,25 @@ double MyDistance(const myVec3& v1, const myVec3& v2); double AngleBetween(myVec3 v1, myVec3 v2); // Matrix 4x4 by 4x1 multiplication -myVec4 MyMatMul4x1(const float *m1, const myVec4& v); +myVec4 MyMatMul4x1(const double *m1, const myVec4& v); // Matrix 4x4 by 4x4 multiplication -void MyMatMul4x4(const float *m1, const float *m2, float* mm); +void MyMatMul4x4(const double *m1, const double *m2, double* mm); // Matrix inverse. Returns the determinant -double MyMatInverse(const float *m, float *minv); +double MyMatInverse(const double *m, double *minv); // Matrix of rotation around an axis in the origin -void MyRotate(const myVec3& axis, double angle, float *mrot); +void MyRotate(const myVec3& axis, double angle, double *mrot); // Matrix for defining the viewing transformation -void MyLookAt(const myVec3& camPos, const myVec3& camUp, const myVec3& targ, float *mt); +void MyLookAt(const myVec3& camPos, const myVec3& camUp, const myVec3& targ, double *mt); // Matrix for defining the perspective projection with symmetric frustum -void MyPerspective(double fov, double aspect, double zNear, double zFar, float *mp); +void MyPerspective(double fov, double aspect, double zNear, double zFar, double *mp); // Matrix for defining the orthogonal projection void MyOrtho(double left, double right, double bottom, double top, - double zNear, double zFar, float *mo); + double zNear, double zFar, double *mo); #endif // MATHSTUFF_H diff --git a/samples/opengl/pyramid/oglstuff.cpp b/samples/opengl/pyramid/oglstuff.cpp index bf17f88513..b2d2eafb5b 100644 --- a/samples/opengl/pyramid/oglstuff.cpp +++ b/samples/opengl/pyramid/oglstuff.cpp @@ -39,6 +39,20 @@ bool MyOnGLError(int err, const GLchar* glMsg = NULL) return err == myoglERR_JUSTLOG ? true : false; } + +// We do calculations with 'doubles'. We pass 'GLFloats' to the shaders +// because OGL added 'doubles' since OGL 4.0, and this sample is for 3.2 +// Due to asynchronous nature of OGL, we can't not trust in the passed matrix +// to be stored by GPU before the passing-function returns. So we don't use +// temporary storage, but dedicated matrices +void SetAsGLFloat4x4(double *matD, GLfloat *matF, int msize) +{ + for (int i = 0; i < msize; i++) + { + matF[i] = (GLfloat) matD[i]; + } +} + // ---------------------------------------------------------------------------- // Data for a regular tetrahedron with edge length 200, centered at the origin // ---------------------------------------------------------------------------- @@ -497,10 +511,10 @@ void myOGLShaders::DisableGenericVAA() void myLight::Set(const myVec3& position, GLfloat intensity, GLfloat R, GLfloat G, GLfloat B) { - m_PosAndIntensisty[0] = position.x; - m_PosAndIntensisty[1] = position.y; - m_PosAndIntensisty[2] = position.z; - m_PosAndIntensisty[3] = intensity; + m_PosAndIntensisty[0] = (GLfloat) position.x; + m_PosAndIntensisty[1] = (GLfloat) position.y; + m_PosAndIntensisty[2] = (GLfloat) position.z; + m_PosAndIntensisty[3] = (GLfloat) intensity; m_Colour[0] = R; m_Colour[1] = G; m_Colour[2] = B; @@ -900,21 +914,27 @@ void myOGLImmutString::SetImmutString(myOGLShaders* theShader, { // Make a rectangle of the same size as the image. Order of vertices matters. // Set a 2 pixels margin - GLfloat imaVerts[12]; + double imaVerts[12]; imaVerts[0] = 2.0 ; imaVerts[1] = 2.0 ; imaVerts[2] = -1.0; imaVerts[3] = 2.0 ; imaVerts[4] = 2.0 + tHeigh; imaVerts[5] = -1.0; imaVerts[6] = 2.0 + tWidth; imaVerts[7] = 2.0 ; imaVerts[8] = -1.0; imaVerts[9] = 2.0 + tWidth; imaVerts[10] = 2.0 + tHeigh; imaVerts[11] = -1.0; + // GLFloat version + GLfloat fimaVerts[12]; + SetAsGLFloat4x4(imaVerts, fimaVerts, 12); + // Call the base class without normals, it will handle this case - SetStringWithVerts(theShader, tImage, tWidth, tHeigh, imaVerts, NULL); + SetStringWithVerts(theShader, tImage, tWidth, tHeigh, fimaVerts, NULL); } void myOGLImmutString::SetOrtho(int winWidth, int winHeight) { // We want an image always of the same size, regardless of window size. // The orthogonal projection with the whole window achieves it. - MyOrtho(0.0, winWidth, 0.0, winHeight, -1.0, 1.0, m_fOrtho); + MyOrtho(0.0, winWidth, 0.0, winHeight, -1.0, 1.0, m_dOrtho); + // Store the 'float' matrix + SetAsGLFloat4x4(m_dOrtho, m_fOrtho, 16); } @@ -966,10 +986,10 @@ void myOGLCamera::InitPositions() m_farD = tmpv + 1.10 * m_radiusOfWorld + 5.0; // The "View" matrix. We will not change it any more in this sample - MyLookAt(m_camPosition, m_camUp, m_camTarget, m_fView); + MyLookAt(m_camPosition, m_camUp, m_camTarget, m_dView); // The initial "Model" matrix is the Identity matrix - MyRotate(myVec3(0.0, 0.0, 1.0), 0.0, m_fMode); + MyRotate(myVec3(0.0, 0.0, 1.0), 0.0, m_dMode); // Nothing else. "View" matrix is calculated at ViewSizeChanged() } @@ -982,7 +1002,7 @@ void myOGLCamera::ViewSizeChanged(int newWidth, int newHeight) // Calculate the projection matrix double aspect = (double) newWidth / newHeight; - MyPerspective(m_fov, aspect, m_nearD, m_farD, m_fProj); + MyPerspective(m_fov, aspect, m_nearD, m_farD, m_dProj); // Inform we need to calculate MVP matrix m_needMVPUpdate = true; @@ -1006,8 +1026,11 @@ void myOGLCamera::UpdateMatrices() { if ( m_needMVPUpdate ) { - MyMatMul4x4(m_fView, m_fMode, m_fToVw); - MyMatMul4x4(m_fProj, m_fToVw, m_fMVP); + MyMatMul4x4(m_dView, m_dMode, m_dToVw); + MyMatMul4x4(m_dProj, m_dToVw, m_dMVP); + // Store the 'float' matrices + SetAsGLFloat4x4(m_dToVw, m_fToVw, 16); + SetAsGLFloat4x4(m_dMVP, m_fMVP, 16); m_needMVPUpdate = false; } } @@ -1037,8 +1060,8 @@ void myOGLCamera::MouseRotation(int fromX, int fromY, int toX, int toY) myVec3 axis(MyCross(v1, v2)); // 'axis' is in camera coordinates. Transform it to world coordinates. - float mtmp[16]; - MyMatInverse(m_fView, mtmp); + double mtmp[16]; + MyMatInverse(m_dView, mtmp); myVec4 res = MyMatMul4x1(mtmp, myVec4(axis)); axis.x = res.x; axis.y = res.y; @@ -1050,10 +1073,10 @@ void myOGLCamera::MouseRotation(int fromX, int fromY, int toX, int toY) // 2. Compute the model transformation (rotate the model) matrix MyRotate(axis, angle, mtmp); // Update "Model" matrix - float mnew[16]; - MyMatMul4x4(mtmp, m_fMode, mnew); + double mnew[16]; + MyMatMul4x4(mtmp, m_dMode, mnew); for (size_t i = 0; i<16; ++i) - m_fMode[i] = mnew[i]; + m_dMode[i] = mnew[i]; // Inform we need to calculate MVP matrix m_needMVPUpdate = true; @@ -1161,19 +1184,19 @@ void myOGLManager::SetStringOnPyr(const unsigned char* strImage, int iWidth, int // If h/rw = Prop then // rw = edgeLength / (1+4/sqrt(3)*Prop) and h = Prop * rw - GLfloat edgeLen = MyDistance(myVec3(gVerts[0], gVerts[1], gVerts[2]), + double edgeLen = MyDistance(myVec3(gVerts[0], gVerts[1], gVerts[2]), myVec3(gVerts[6], gVerts[7], gVerts[8])); - GLfloat prop = (double) iHeigh / iWidth; - GLfloat rw = (double) edgeLen / (1 + 4.0 * prop / sqrt(3.0)); + GLfloat prop = ((GLfloat) iHeigh) / ((GLfloat) iWidth); + GLfloat rw = (GLfloat) (edgeLen / (1 + 4.0 * prop / sqrt(3.0))); GLfloat h = prop * rw; - GLfloat de = 2.0 * h / sqrt(3.0); + GLfloat de = (GLfloat)(2.0 * h / sqrt(3.0)); // A bit of separation of the face so as to avoid z-fighting - GLfloat rY = gVerts[1] - 0.01; // Towards outside + GLfloat rY = gVerts[1] - (GLfloat)0.01; // Towards outside GLfloat sVerts[12]; // The image was created top to bottom, but OpenGL axis are bottom to top. // The image would display upside down. We avoid it choosing the right // order of vertices and texture coords. See myOGLString::SetStringWithVerts() - sVerts[0] = gVerts[6] + de; sVerts[1] = rY; sVerts[2] = gVerts[8] + h / 2.0; + sVerts[0] = gVerts[6] + de; sVerts[1] = rY; sVerts[2] = gVerts[8] + h / (GLfloat)2.0; sVerts[3] = sVerts[0] ; sVerts[4] = rY; sVerts[5] = sVerts[2] + h; sVerts[6] = sVerts[0] + rw; sVerts[7] = rY; sVerts[8] = sVerts[2]; sVerts[9] = sVerts[6] ; sVerts[10] = rY; sVerts[11] = sVerts[5]; @@ -1215,7 +1238,7 @@ void myOGLManager::Render() glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - glClearColor(0.15, 0.15, 0.0 ,1.0); // Dark, but not black. Isn't it nice? + glClearColor((GLfloat)0.15, (GLfloat)0.15, 0.0, (GLfloat)1.0); // Dark, but not black. glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ); m_Triangles.Draw(m_Camera.GetFloatMVP(), m_Camera.GetFloatToVw(), &m_Light); @@ -1238,4 +1261,3 @@ void myOGLManager::OnMouseRotDragging(int posX, int posY) m_mousePrevX = posX; m_mousePrevY = posY; } - diff --git a/samples/opengl/pyramid/oglstuff.h b/samples/opengl/pyramid/oglstuff.h index edaa6e7776..010920c2ec 100644 --- a/samples/opengl/pyramid/oglstuff.h +++ b/samples/opengl/pyramid/oglstuff.h @@ -230,7 +230,8 @@ public: const GLfloat* GetFloatMVP() { return m_fOrtho; } private: - GLfloat m_fOrtho[16]; // The orthogonal projection matrix + double m_dOrtho[16]; // The orthogonal projection matrix + GLfloat m_fOrtho[16]; // Same as float }; //----------------------------------------------------------------------------- @@ -257,11 +258,14 @@ public: double GetTrackballZ(double x, double y, double r); // The used matrices - GLfloat m_fMode[16]; // The model matrix, rotation in this sample - GLfloat m_fView[16]; // The view matrix - GLfloat m_fProj[16]; // The projection matrix - GLfloat m_fMVP[16]; // The whole transform matrix - GLfloat m_fToVw[16]; // The 'to View' transform matrix + double m_dMode[16]; // The model matrix, rotation in this sample + double m_dView[16]; // The view matrix + double m_dProj[16]; // The projection matrix + double m_dMVP[16]; // The whole transform matrix + double m_dToVw[16]; // The 'to View' transform matrix + // GLFloat versions. GLdouble is available since OGL 4.0, and we use 3.2 + GLfloat m_fMVP[16]; + GLfloat m_fToVw[16]; private: bool m_needMVPUpdate;