6 #include "glwrapper-ogl.h"
8 // How do we get access to the GL calls?
9 // If other UI types use the -ogl wrapper they should
10 // include more conditional includes here.
17 #include <SDL_opengl.h>
23 /////////////////////////////////////////////////////////////////////////////
24 // Static functions from GLStateManager
26 GLStateManager
*glmanager
= NULL
;
28 void GLStateManager::init()
33 glmanager
= new OGLStateManager();
36 void GLStateManager::shutdown()
42 /////////////////////////////////////////////////////////////////////////////
43 // Static functions from GLShapeBuffer
45 GLShapeBuffer
*GLShapeBuffer::create(bool texture
, bool colour
,
48 return (new OGLShapeBuffer(texture
, colour
, prim
));
51 /////////////////////////////////////////////////////////////////////////////
54 OGLStateManager::OGLStateManager()
56 glBlendFunc(GL_SRC_ALPHA
, GL_ONE_MINUS_SRC_ALPHA
);
57 glClearColor(0.0, 0.0, 0.0, 1.0f
);
58 glDepthFunc(GL_LEQUAL
);
61 void OGLStateManager::set(const GLState
& state
)
63 if (state
.array_vertex
!= m_current_state
.array_vertex
)
65 if (state
.array_vertex
)
66 glEnableClientState(GL_VERTEX_ARRAY
);
68 glDisableClientState(GL_VERTEX_ARRAY
);
71 if (state
.array_texcoord
!= m_current_state
.array_texcoord
)
73 if (state
.array_texcoord
)
74 glEnableClientState(GL_TEXTURE_COORD_ARRAY
);
76 glDisableClientState(GL_TEXTURE_COORD_ARRAY
);
79 if (state
.array_colour
!= m_current_state
.array_colour
)
81 if (state
.array_colour
)
83 glEnableClientState(GL_COLOR_ARRAY
);
87 glDisableClientState(GL_COLOR_ARRAY
);
89 // [enne] This should *not* be necessary, but the Linux OpenGL
90 // driver that I'm using sets this to the last colour of the
91 // colour array. So, we need to unset it here.
92 glColor4f(1.0f
, 1.0f
, 1.0f
, 1.0f
);
96 if (state
.texture
!= m_current_state
.texture
)
99 glEnable(GL_TEXTURE_2D
);
101 glDisable(GL_TEXTURE_2D
);
104 if (state
.blend
!= m_current_state
.blend
)
112 if (state
.depthtest
!= m_current_state
.depthtest
)
115 glEnable(GL_DEPTH_TEST
);
117 glDisable(GL_DEPTH_TEST
);
120 if (state
.alphatest
!= m_current_state
.alphatest
121 || state
.alpharef
!= m_current_state
.alpharef
)
125 glEnable(GL_ALPHA_TEST
);
126 glAlphaFunc(GL_NOTEQUAL
, state
.alpharef
);
129 glDisable(GL_ALPHA_TEST
);
132 if (state
.colour
!= m_current_state
.colour
)
134 glColor4f(state
.colour
.r
, state
.colour
.g
,
135 state
.colour
.b
, state
.colour
.a
);
138 m_current_state
= state
;
141 void OGLStateManager::set_transform(const GLW_3VF
&trans
, const GLW_3VF
&scale
)
144 glTranslatef(trans
.x
, trans
.y
, trans
.z
);
145 glScalef(scale
.x
, scale
.y
, scale
.z
);
148 void OGLStateManager::reset_view_for_resize(const coord_def
&m_windowsz
)
150 glMatrixMode(GL_PROJECTION
);
153 // For ease, vertex positions are pixel positions.
155 glOrthox(0, m_windowsz
.x
, m_windowsz
.y
, 0, -1000, 1000);
157 glOrtho(0, m_windowsz
.x
, m_windowsz
.y
, 0, -1000, 1000);
161 void OGLStateManager::reset_transform()
168 void OGLStateManager::pixelstore_unpack_alignment(unsigned int bpp
)
170 glPixelStorei(GL_UNPACK_ALIGNMENT
, bpp
);
173 void OGLStateManager::delete_textures(size_t count
, unsigned int *textures
)
175 glDeleteTextures(count
, (GLuint
*)textures
);
178 void OGLStateManager::generate_textures(size_t count
, unsigned int *textures
)
180 glGenTextures(count
, (GLuint
*)textures
);
183 void OGLStateManager::bind_texture(unsigned int texture
)
185 glBindTexture(GL_TEXTURE_2D
, texture
);
188 void OGLStateManager::load_texture(unsigned char *pixels
, unsigned int width
,
189 unsigned int height
, MipMapOptions mip_opt
)
192 const unsigned int bpp
= 4;
193 const GLenum texture_format
= GL_RGBA
;
194 const GLenum format
= GL_UNSIGNED_BYTE
;
195 // Also assume that the texture is already bound using bind_texture
197 glTexEnvf(GL_TEXTURE_ENV
, GL_TEXTURE_ENV_MODE
, GL_MODULATE
);
199 glTexParameterf(GL_TEXTURE_2D
, GL_TEXTURE_WRAP_S
, GL_CLAMP
);
200 glTexParameterf(GL_TEXTURE_2D
, GL_TEXTURE_WRAP_T
, GL_CLAMP
);
202 glTexParameterf(GL_TEXTURE_2D
, GL_TEXTURE_WRAP_S
, GL_CLAMP_TO_EDGE
);
203 glTexParameterf(GL_TEXTURE_2D
, GL_TEXTURE_WRAP_T
, GL_CLAMP_TO_EDGE
);
206 if (mip_opt
== MIPMAP_CREATE
)
208 glTexParameterf(GL_TEXTURE_2D
, GL_TEXTURE_MIN_FILTER
,
209 GL_LINEAR_MIPMAP_NEAREST
);
210 glTexParameterf(GL_TEXTURE_2D
, GL_TEXTURE_MAG_FILTER
, GL_LINEAR
);
211 gluBuild2DMipmaps(GL_TEXTURE_2D
, bpp
, width
, height
,
212 texture_format
, format
, pixels
);
217 glTexParameterf(GL_TEXTURE_2D
, GL_TEXTURE_MIN_FILTER
, GL_NEAREST
);
218 glTexParameterf(GL_TEXTURE_2D
, GL_TEXTURE_MAG_FILTER
, GL_NEAREST
);
219 glTexImage2D(GL_TEXTURE_2D
, 0, bpp
, width
, height
, 0,
220 texture_format
, format
, pixels
);
224 void OGLStateManager::reset_view_for_redraw(float x
, float y
)
226 glClear(GL_COLOR_BUFFER_BIT
| GL_DEPTH_BUFFER_BIT
);
227 glMatrixMode(GL_MODELVIEW
);
229 glTranslatef(x
, y
, 1.0f
);
232 /////////////////////////////////////////////////////////////////////////////
235 OGLShapeBuffer::OGLShapeBuffer(bool texture
, bool colour
, drawing_modes prim
) :
237 m_texture_verts(texture
),
238 m_colour_verts(colour
)
240 ASSERT(prim
== GLW_RECTANGLE
|| prim
== GLW_LINES
);
243 const char *OGLShapeBuffer::print_statistics() const
248 unsigned int OGLShapeBuffer::size() const
250 return (m_position_buffer
.size());
253 void OGLShapeBuffer::add(const GLWPrim
&rect
)
264 die("Invalid primitive type");
269 void OGLShapeBuffer::add_rect(const GLWPrim
&rect
)
271 // Copy vert positions
272 size_t last
= m_position_buffer
.size();
273 m_position_buffer
.resize(last
+ 4);
274 m_position_buffer
[last
].set(rect
.pos_sx
, rect
.pos_sy
, rect
.pos_z
);
275 m_position_buffer
[last
+ 1].set(rect
.pos_sx
, rect
.pos_ey
, rect
.pos_z
);
276 m_position_buffer
[last
+ 2].set(rect
.pos_ex
, rect
.pos_sy
, rect
.pos_z
);
277 m_position_buffer
[last
+ 3].set(rect
.pos_ex
, rect
.pos_ey
, rect
.pos_z
);
279 // Copy texture coords if necessary
282 last
= m_texture_buffer
.size();
283 m_texture_buffer
.resize(last
+ 4);
284 m_texture_buffer
[last
].set(rect
.tex_sx
, rect
.tex_sy
);
285 m_texture_buffer
[last
+ 1].set(rect
.tex_sx
, rect
.tex_ey
);
286 m_texture_buffer
[last
+ 2].set(rect
.tex_ex
, rect
.tex_sy
);
287 m_texture_buffer
[last
+ 3].set(rect
.tex_ex
, rect
.tex_ey
);
290 // Copy vert colours if necessary
293 last
= m_colour_buffer
.size();
294 m_colour_buffer
.resize(last
+ 4);
295 m_colour_buffer
[last
].set(rect
.col_s
);
296 m_colour_buffer
[last
+ 1].set(rect
.col_e
);
297 m_colour_buffer
[last
+ 2].set(rect
.col_s
);
298 m_colour_buffer
[last
+ 3].set(rect
.col_e
);
302 last
= m_ind_buffer
.size();
306 // This is not the first box so make FOUR degenerate triangles
307 m_ind_buffer
.resize(last
+ 6);
308 unsigned short int val
= m_ind_buffer
[last
- 1];
310 // the first three degens finish the previous box and move
311 // to the first position of the new one we just added and
312 // the fourth degen creates a triangle that is a line from p1 to p3
313 m_ind_buffer
[last
] = val
++;
314 m_ind_buffer
[last
+ 1] = val
;
317 m_ind_buffer
[last
+ 2] = val
++;
318 m_ind_buffer
[last
+ 3] = val
++;
319 m_ind_buffer
[last
+ 4] = val
++;
320 m_ind_buffer
[last
+ 5] = val
;
324 // This is the first box so don't bother making any degenerate triangles
325 m_ind_buffer
.resize(last
+ 4);
333 void OGLShapeBuffer::add_line(const GLWPrim
&rect
)
335 // Copy vert positions
336 size_t last
= m_position_buffer
.size();
337 m_position_buffer
.resize(last
+ 2);
338 m_position_buffer
[last
].set(rect
.pos_sx
, rect
.pos_sy
, rect
.pos_z
);
339 m_position_buffer
[last
+ 1].set(rect
.pos_ex
, rect
.pos_ey
, rect
.pos_z
);
341 // Copy texture coords if necessary
344 last
= m_texture_buffer
.size();
345 m_texture_buffer
.resize(last
+ 2);
346 m_texture_buffer
[last
].set(rect
.tex_sx
, rect
.tex_sy
);
347 m_texture_buffer
[last
+ 1].set(rect
.tex_ex
, rect
.tex_ey
);
350 // Copy vert colours if necessary
353 last
= m_colour_buffer
.size();
354 m_colour_buffer
.resize(last
+ 2);
355 m_colour_buffer
[last
].set(rect
.col_s
);
356 m_colour_buffer
[last
+ 1].set(rect
.col_e
);
362 void OGLShapeBuffer::draw(const GLState
&state
, const GLW_3VF
*pt
, const GLW_3VF
*ps
)
364 void OGLShapeBuffer::draw(const GLState
&state
)
366 if (m_position_buffer
.size() == 0)
369 if (!state
.array_vertex
)
372 glmanager
->set(state
);
374 glVertexPointer(3, GL_FLOAT
, 0, &m_position_buffer
[0]);
376 if (state
.array_texcoord
&& m_texture_verts
)
377 glTexCoordPointer(2, GL_FLOAT
, 0, &m_texture_buffer
[0]);
379 if (state
.array_colour
&& m_colour_verts
)
380 glColorPointer(4, GL_UNSIGNED_BYTE
, 0, &m_colour_buffer
[0]);
385 glDrawElements(GL_TRIANGLE_STRIP
, m_ind_buffer
.size(),
386 GL_UNSIGNED_SHORT
, &m_ind_buffer
[0]);
389 glDrawArrays(GL_LINES
, 0, m_position_buffer
.size());
392 die("Invalid primitive type");
397 void OGLShapeBuffer::clear()
399 m_position_buffer
.clear();
400 m_ind_buffer
.clear();
401 m_texture_buffer
.clear();
402 m_colour_buffer
.clear();