KiCad PCB EDA Suite
ogl_utils.cpp
Go to the documentation of this file.
1 /*
2  * This program source code file is part of KiCad, a free EDA CAD application.
3  *
4  * Copyright (C) 2015-2016 Mario Luzeiro <[email protected]>
5  * Copyright (C) 1992-2020 KiCad Developers, see AUTHORS.txt for contributors.
6  *
7  * This program is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License
9  * as published by the Free Software Foundation; either version 2
10  * of the License, or (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, you may find one here:
19  * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
20  * or you may search the http://www.gnu.org website for the version 2 license,
21  * or you may write to the Free Software Foundation, Inc.,
22  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
23  */
24 
30 #include <stdexcept>
31 #include <gal/opengl/kiglew.h> // Must be included first
32 
33 #include "openGL_includes.h"
34 #include "ogl_utils.h"
35 
36 
37 void OglGetScreenshot( wxImage& aDstImage )
38 {
39  struct viewport_params
40  {
41  GLint originX;
42  GLint originY;
43  GLint x;
44  GLint y;
45  } viewport;
46 
47  glGetIntegerv( GL_VIEWPORT, (GLint*) &viewport );
48 
49  unsigned char* pixelbuffer = (unsigned char*) malloc( viewport.x * viewport.y * 3 );
50 
51  // Call glFinish before screenshot to ensure everything is fully drawn.
52  glFinish();
53 
54  glPixelStorei( GL_PACK_ALIGNMENT, 1 );
55  glReadBuffer( GL_BACK_LEFT );
56 
57  glReadPixels( viewport.originX, viewport.originY, viewport.x, viewport.y, GL_RGB,
58  GL_UNSIGNED_BYTE, pixelbuffer );
59 
60  // "Sets the image data without performing checks.
61  // The data given must have the size (width*height*3)
62  // The data must have been allocated with malloc()
63  // If static_data is false, after this call the pointer to the data is owned
64  // by the wxImage object, that will be responsible for deleting it."
65  aDstImage.SetData( pixelbuffer, viewport.x, viewport.y, false );
66 
67  aDstImage = aDstImage.Mirror( false );
68 }
69 
70 
71 GLuint OglLoadTexture( const IMAGE& aImage )
72 {
73  unsigned char* rgbaBuffer = (unsigned char*) malloc( aImage.GetWidth() *
74  aImage.GetHeight() * 4 );
75 
76  unsigned char* dst = rgbaBuffer;
77  const unsigned char* ori = aImage.GetBuffer();
78 
79  for( unsigned int i = 0; i < ( aImage.GetWidth() * aImage.GetHeight() ); ++i )
80  {
81  unsigned char v = *ori;
82 
83  ori++;
84 
85  dst[0] = 255;
86  dst[1] = 255;
87  dst[2] = 255;
88  dst[3] = v;
89  dst+= 4;
90  }
91 
92  GLuint texture;
93  glPixelStorei( GL_UNPACK_ALIGNMENT, 4 );
94  glPixelStorei( GL_PACK_ALIGNMENT, 4 );
95 
96  glGenTextures( 1, &texture );
97  glBindTexture( GL_TEXTURE_2D, texture );
98 
99  glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, aImage.GetWidth(), aImage.GetHeight(), 0, GL_RGBA,
100  GL_UNSIGNED_BYTE, rgbaBuffer );
101 
102  glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
103  glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
104  glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT );
105  glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT );
106 
107  glTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );
108 
109  glBindTexture( GL_TEXTURE_2D, 0 );
110 
111  glFlush();
112 
113  free( rgbaBuffer );
114 
115  return texture;
116 }
117 
118 
119 void OglSetMaterial( const SMATERIAL& aMaterial, float aOpacity, bool aUseSelectedMaterial,
120  SFVEC3F aSelectionColor )
121 {
122  const SFVEC4F ambient = SFVEC4F( aMaterial.m_Ambient, 1.0f );
123 
124  // !TODO: at this moment, diffuse color is added via
125  // glEnableClientState( GL_COLOR_ARRAY ) so this line may has no effect
126  // but can be used for optimization
127  const SFVEC4F diffuse = SFVEC4F( aUseSelectedMaterial ? aSelectionColor : aMaterial.m_Diffuse,
128  ( 1.0f - aMaterial.m_Transparency ) * aOpacity );
129  const SFVEC4F specular = SFVEC4F( aMaterial.m_Specular, 1.0f );
130  const SFVEC4F emissive = SFVEC4F( aMaterial.m_Emissive, 1.0f );
131 
132  const float shininess =
133  128.0f * ( (aMaterial.m_Shininess > 1.0f) ? 1.0f : aMaterial.m_Shininess );
134 
135  glMaterialfv( GL_FRONT_AND_BACK, GL_AMBIENT, &ambient.r );
136  glMaterialfv( GL_FRONT_AND_BACK, GL_DIFFUSE, &diffuse.r );
137  glMaterialfv( GL_FRONT_AND_BACK, GL_SPECULAR, &specular.r );
138  glMaterialfv( GL_FRONT_AND_BACK, GL_EMISSION, &emissive.r );
139  glMaterialf( GL_FRONT_AND_BACK, GL_SHININESS, shininess );
140 }
141 
142 
143 void OglSetDiffuseMaterial( const SFVEC3F &aMaterialDiffuse, float aOpacity,
144  bool aUseSelectedMaterial, SFVEC3F aSelectionColor )
145 {
146  const SFVEC4F ambient = SFVEC4F( 0.2f, 0.2f, 0.2f, 1.0f );
147  const SFVEC4F diffuse = SFVEC4F( aUseSelectedMaterial ? aSelectionColor : aMaterialDiffuse,
148  aOpacity );
149  const SFVEC4F specular = SFVEC4F( 0.0f, 0.0f, 0.0f, 1.0f );
150  const SFVEC4F emissive = SFVEC4F( 0.0f, 0.0f, 0.0f, 1.0f );
151 
152  glMaterialfv( GL_FRONT_AND_BACK, GL_AMBIENT, &ambient.r );
153  glMaterialfv( GL_FRONT_AND_BACK, GL_DIFFUSE, &diffuse.r );
154  glMaterialfv( GL_FRONT_AND_BACK, GL_SPECULAR, &specular.r );
155  glMaterialfv( GL_FRONT_AND_BACK, GL_EMISSION, &emissive.r );
156  glMaterialf( GL_FRONT_AND_BACK, GL_SHININESS, 0.0f );
157 }
158 
159 
160 void OglDrawBackground( const SFVEC3F& aTopColor, const SFVEC3F& aBotColor )
161 {
162  glMatrixMode( GL_PROJECTION );
163  glLoadIdentity();
164 
165  glMatrixMode( GL_MODELVIEW );
166  glLoadIdentity();
167 
168  glDisable( GL_LIGHTING );
169  glDisable( GL_COLOR_MATERIAL );
170  glDisable( GL_DEPTH_TEST );
171  glDisable( GL_TEXTURE_2D );
172  glDisable( GL_BLEND );
173  glDisable( GL_ALPHA_TEST );
174 
175  glBegin( GL_QUADS );
176  glColor4f( aTopColor.x, aTopColor.y, aTopColor.z, 1.0f );
177  glVertex2f( -1.0, 1.0 ); // Top left corner
178 
179  glColor4f( aBotColor.x, aBotColor.y, aBotColor.z, 1.0f );
180  glVertex2f( -1.0,-1.0 ); // bottom left corner
181  glVertex2f( 1.0,-1.0 ); // bottom right corner
182 
183  glColor4f( aTopColor.x, aTopColor.y, aTopColor.z, 1.0f );
184  glVertex2f( 1.0, 1.0 ); // top right corner
185  glEnd();
186 }
187 
188 
190 {
191  if( !glActiveTexture || !glClientActiveTexture )
192  throw std::runtime_error( "The OpenGL context no longer exists: unable to Reset Textures" );
193 
194  glActiveTexture( GL_TEXTURE0 );
195  glBindTexture( GL_TEXTURE_2D, 0 );
196  glClientActiveTexture( GL_TEXTURE0 );
197  glDisable( GL_TEXTURE_2D );
198  glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );
199 
200  const SFVEC4F zero = SFVEC4F( 0.0f );
201 
202  glTexEnvfv( GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, static_cast<const float*>( &zero.x ) );
203 }
unsigned char * GetBuffer() const
Get the image buffer pointer.
Definition: image.cpp:73
SFVEC3F m_Ambient
Definition: c3dmodel.h:39
void OglSetDiffuseMaterial(const SFVEC3F &aMaterialDiffuse, float aOpacity, bool aUseSelectedMaterial, SFVEC3F aSelectionColor)
Sets only the diffuse color and keep other parameters with default values.
Definition: ogl_utils.cpp:143
void OglSetMaterial(const SMATERIAL &aMaterial, float aOpacity, bool aUseSelectedMaterial, SFVEC3F aSelectionColor)
Set OpenGL materials.
Definition: ogl_utils.cpp:119
glm::vec4 SFVEC4F
Definition: xv3d_types.h:46
float m_Transparency
1.0 is completely transparent, 0.0 completely opaque
Definition: c3dmodel.h:44
void OglResetTextureState()
Reset to default state the texture settings.
Definition: ogl_utils.cpp:189
float m_Shininess
Definition: c3dmodel.h:43
void OglDrawBackground(const SFVEC3F &aTopColor, const SFVEC3F &aBotColor)
Definition: ogl_utils.cpp:160
SFVEC3F m_Emissive
Definition: c3dmodel.h:41
glm::vec3 SFVEC3F
Definition: xv3d_types.h:44
unsigned int GetHeight() const
Definition: image.h:214
includes in a proper way the openGL related includes
Define generic OpenGL functions that are common to any OpenGL target.
Manage an 8-bit channel image.
Definition: image.h:89
SFVEC3F m_Diffuse
Default diffuse color if m_Color is NULL.
Definition: c3dmodel.h:40
unsigned int GetWidth() const
Definition: image.h:213
GLuint OglLoadTexture(const IMAGE &aImage)
Generate a new OpenGL texture.
Definition: ogl_utils.cpp:71
void OglGetScreenshot(wxImage &aDstImage)
Get the pixel data of current OpenGL image.
Definition: ogl_utils.cpp:37
SFVEC3F m_Specular
Definition: c3dmodel.h:42