0023012: Detection gives incorrect results
[occt.git] / src / OpenGl / OpenGl_GraphicDriver_9.cxx
1 // Created on: 2011-10-20
2 // Created by: Sergey ZERCHANINOV
3 // Copyright (c) 2011-2012 OPEN CASCADE SAS
4 //
5 // The content of this file is subject to the Open CASCADE Technology Public
6 // License Version 6.5 (the "License"). You may not use the content of this file
7 // except in compliance with the License. Please obtain a copy of the License
8 // at http://www.opencascade.org and read it completely before using this file.
9 //
10 // The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
11 // main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
12 //
13 // The Original Code and all software distributed under the License is
14 // distributed on an "AS IS" basis, without warranty of any kind, and the
15 // Initial Developer hereby disclaims all such warranties, including without
16 // limitation, any warranties of merchantability, fitness for a particular
17 // purpose or non-infringement. Please see the License for the specific terms
18 // and conditions governing the rights and limitations under the License.
19
20
21 #include <OpenGl_GraphicDriver.hxx>
22 #include <OpenGl_CView.hxx>
23 #include <OpenGl_Trihedron.hxx>
24 #include <OpenGl_GraduatedTrihedron.hxx>
25 #include <OpenGl_TextureBox.hxx>
26 #include <OpenGl_tgl_funcs.hxx>
27
28 #include <Quantity_NameOfColor.hxx>
29 #include <TColStd_HArray1OfReal.hxx>
30 #include <AlienImage_AlienImage.hxx>
31 #include <Image_Image.hxx>
32
33 void OpenGl_GraphicDriver::Environment(const Graphic3d_CView& ACView)
34 {
35   const OpenGl_CView *aCView = (const OpenGl_CView *)ACView.ptrView;
36   if (aCView)
37   {
38     aCView->View->SetTextureEnv(ACView.Context.TexEnvId);
39     aCView->View->SetSurfaceDetail((Visual3d_TypeOfSurfaceDetail)ACView.Context.SurfaceDetail);
40   }
41 }
42
43 //
44 // Triedron methods : the Triedron is a non-zoomable object.
45 //
46
47 void OpenGl_GraphicDriver::ZBufferTriedronSetup (
48   const Quantity_NameOfColor XColor,
49   const Quantity_NameOfColor YColor,
50   const Quantity_NameOfColor ZColor,
51   const Standard_Real        SizeRatio,
52   const Standard_Real        AxisDiametr,
53   const Standard_Integer     NbFacettes)
54 {
55   OpenGl_Trihedron::Setup(XColor,YColor,ZColor,SizeRatio,AxisDiametr,NbFacettes);
56 }
57
58 void OpenGl_GraphicDriver::TriedronDisplay (
59   const Graphic3d_CView& ACView,
60   const Aspect_TypeOfTriedronPosition APosition,
61   const Quantity_NameOfColor AColor, 
62   const Standard_Real AScale,
63   const Standard_Boolean AsWireframe )
64 {
65   const OpenGl_CView *aCView = (const OpenGl_CView *)ACView.ptrView;
66   if (aCView)
67   {
68     aCView->View->TriedronDisplay(APosition, AColor, AScale, AsWireframe);
69     aCView->WS->Invalidate();
70   }
71 }
72
73 void OpenGl_GraphicDriver::TriedronErase (const Graphic3d_CView& ACView) 
74 {
75   const OpenGl_CView *aCView = (const OpenGl_CView *)ACView.ptrView;
76   if (aCView)
77   {
78     aCView->View->TriedronErase();
79     aCView->WS->Invalidate();
80   }
81 }
82
83 void OpenGl_GraphicDriver::TriedronEcho (const Graphic3d_CView& ACView,const Aspect_TypeOfTriedronEcho AType )
84 {
85   // Do nothing
86 }
87
88 void OpenGl_GraphicDriver::BackgroundImage( const Standard_CString FileName, 
89                                            const Graphic3d_CView& ACView,
90                                            const Aspect_FillMethod FillStyle )
91 {
92   const OpenGl_CView *aCView = (const OpenGl_CView *)ACView.ptrView;
93   if (aCView)
94   {
95     aCView->View->CreateBackgroundTexture( FileName, FillStyle );
96     aCView->WS->Invalidate();
97   }
98 }
99
100 void OpenGl_GraphicDriver::SetBgImageStyle( const Graphic3d_CView& ACView,
101                                            const Aspect_FillMethod FillStyle )
102 {
103   const OpenGl_CView *aCView = (const OpenGl_CView *)ACView.ptrView;
104   if (aCView)
105   {
106     aCView->View->SetBackgroundTextureStyle( FillStyle );
107     aCView->WS->Invalidate();
108   }
109 }
110
111 void OpenGl_GraphicDriver::SetBgGradientStyle(const Graphic3d_CView& ACView,const Aspect_GradientFillMethod FillType)
112 {
113   const OpenGl_CView *aCView = (const OpenGl_CView *)ACView.ptrView;
114   if (aCView)
115   {
116     aCView->View->SetBackgroundGradientType(FillType);
117     aCView->WS->Invalidate();
118   }
119 }
120
121 void OpenGl_GraphicDriver::GraduatedTrihedronDisplay(const Graphic3d_CView& ACView, const Graphic3d_CGraduatedTrihedron& cubic)
122 {
123   const OpenGl_CView *aCView = (const OpenGl_CView *)ACView.ptrView;
124   if (aCView)
125   {
126     aCView->View->GraduatedTrihedronDisplay(cubic);
127     aCView->WS->Invalidate();
128   }
129 }
130
131 void OpenGl_GraphicDriver::GraduatedTrihedronErase(const Graphic3d_CView& ACView)
132 {
133   const OpenGl_CView *aCView = (const OpenGl_CView *)ACView.ptrView;
134   if (aCView)
135   {
136     aCView->View->GraduatedTrihedronErase();
137     aCView->WS->Invalidate();
138   }
139 }
140
141 void OpenGl_GraphicDriver::GraduatedTrihedronMinMaxValues(const Standard_ShortReal xmin,
142                                                          const Standard_ShortReal ymin,
143                                                          const Standard_ShortReal zmin,
144                                                          const Standard_ShortReal xmax,
145                                                          const Standard_ShortReal ymax,
146                                                          const Standard_ShortReal zmax)
147 {
148   OpenGl_GraduatedTrihedron::SetMinMax(xmin, ymin, zmin, xmax, ymax, zmax);
149 }
150
151 // Helper function, returns the nearest power of two greater than the argument value
152 inline Standard_Integer GetNearestPow2(Standard_Integer theValue)
153 {
154   // Precaution against overflow
155   Standard_Integer aHalfMax = IntegerLast() >> 1, aRes = 1;
156   if ( theValue > aHalfMax ) theValue = aHalfMax;
157   while ( aRes < theValue ) aRes <<= 1;
158   return aRes;
159 }
160
161 Standard_Integer OpenGl_GraphicDriver::CreateTexture (const Graphic3d_TypeOfTexture Type,
162                                                       const Handle_AlienImage_AlienImage &Image,
163                                                                                                           const Standard_CString FileName,
164                                                                                                           const Handle(TColStd_HArray1OfReal)& TexUpperBounds) const
165 {
166   Handle(Image_Image) MyPic = Image->ToImage();
167
168   Standard_Integer aGlWidth  = (Type == Graphic3d_TOT_2D_MIPMAP) ? MyPic->Width() : GetNearestPow2(MyPic->Width());
169   Standard_Integer aGlHeight = (Type == Graphic3d_TOT_2D_MIPMAP) ? MyPic->Height() : GetNearestPow2(MyPic->Height());
170
171   TexUpperBounds->SetValue(1, ((Standard_Real) (MyPic->Width())/((Standard_Real) aGlWidth)));
172   TexUpperBounds->SetValue(2, ((Standard_Real) (MyPic->Height())/((Standard_Real) aGlHeight)));
173
174   unsigned char *MyImageData = (unsigned char *)malloc(aGlWidth*aGlHeight*4);
175   unsigned char *MyData = MyImageData;
176   int TexId;
177   int i,j;
178   Quantity_Color MyColor;
179
180   if (MyImageData == NULL)
181     return -1;
182
183   static Standard_Integer textureRank=0;  
184   char textureName[16];
185   Standard_PCharacter fileName = textureName; 
186   sprintf(fileName,"Tex%d",++textureRank);
187
188     for (j = MyPic->Height() - 1; j >= 0; j--)
189       for (i = 0; i < aGlWidth; i++){
190         if (i < MyPic->Width()){
191           MyColor = MyPic->PixelColor(i, j);
192           *MyData++ = (int)(255 * MyColor.Red());
193           *MyData++ = (int)(255 * MyColor.Green());
194           *MyData++ = (int)(255 * MyColor.Blue());
195         }
196         else {
197           *MyData++ = (int)(0);
198           *MyData++ = (int)(0);
199           *MyData++ = (int)(0);
200         }
201         *MyData++ = 0xFF;
202       }
203
204       // Padding the lower part of the texture with black
205       for (j = aGlHeight - 1; j >= MyPic->Height(); j--)
206         for (i = 0; i < aGlWidth; i++){
207           *MyData++ = (int)(0);
208           *MyData++ = (int)(0);
209           *MyData++ = (int)(0);
210           *MyData++ = 0xFF;
211         }  
212
213         switch (Type)
214         {
215         case Graphic3d_TOT_1D:
216           TexId = GetTextureData1D (fileName, aGlWidth, aGlHeight, MyImageData);
217           break;
218
219         case Graphic3d_TOT_2D:
220           TexId = GetTextureData2D (fileName, aGlWidth, aGlHeight, MyImageData);
221           break;
222
223         case Graphic3d_TOT_2D_MIPMAP:
224           TexId = GetTextureData2DMipMap (fileName, aGlWidth, aGlHeight, MyImageData);
225           break;
226
227         default:
228           TexId = -1;
229         }
230
231         free(MyImageData);
232         return TexId;
233
234 }
235
236 void OpenGl_GraphicDriver::DestroyTexture (const Standard_Integer theTexId) const
237 {
238   FreeTexture (theTexId);
239 }
240
241 void OpenGl_GraphicDriver::ModifyTexture (const Standard_Integer        theTexId,
242                                           const Graphic3d_CInitTexture& theInfo) const
243 {
244   if (theInfo.doModulate)
245     SetTextureModulate (theTexId);
246   else
247     SetTextureDecal (theTexId);
248
249   if (theInfo.doRepeat)
250     SetTextureRepeat (theTexId);
251   else
252     SetTextureClamp (theTexId);
253
254   switch (theInfo.Mode)
255   {
256     case 0:
257       SetModeObject (theTexId, theInfo.sparams, theInfo.tparams);
258       break;
259
260     case 1:
261       SetModeSphere (theTexId);
262       break;
263
264     case 2:
265       SetModeEye (theTexId, theInfo.sparams, theInfo.tparams);
266       break;
267
268     case 3:
269       SetModeManual (theTexId);
270       break;        
271   }
272
273   if (theInfo.doLinear)
274     SetRenderLinear (theTexId);
275   else
276     SetRenderNearest (theTexId);
277
278   SetTexturePosition (theTexId,
279                       theInfo.sx, theInfo.sy,
280                       theInfo.tx, theInfo.ty,
281                       theInfo.angle);
282 }