naev 0.12.5
opengl_render.c
Go to the documentation of this file.
1/*
2 * See Licensing and Copyright notice in naev.h
3 */
27#include "naev.h"
29
30#include "opengl_render.h"
31
32#include "camera.h"
33#include "gui.h"
34#include "opengl.h"
35
36#define OPENGL_RENDER_VBO_SIZE 256
37
38static gl_vbo *gl_renderVBO = 0;
39gl_vbo *gl_squareVBO = 0;
40static gl_vbo *gl_squareEmptyVBO = 0;
41gl_vbo *gl_circleVBO = 0;
42static gl_vbo *gl_lineVBO = 0;
43static gl_vbo *gl_triangleVBO = 0;
44static int gl_renderVBOtexOffset = 0;
45static int gl_renderVBOcolOffset = 0;
46
47void gl_beginSolidProgram( mat4 projection, const glColour *c )
48{
49 glUseProgram( shaders.solid.program );
50 glEnableVertexAttribArray( shaders.solid.vertex );
51 gl_uniformColour( shaders.solid.colour, c );
52 gl_uniformMat4( shaders.solid.projection, &projection );
53}
54
55void gl_endSolidProgram( void )
56{
57 glDisableVertexAttribArray( shaders.solid.vertex );
58 glUseProgram( 0 );
59 gl_checkErr();
60}
61
62void gl_beginSmoothProgram( mat4 projection )
63{
64 glUseProgram( shaders.smooth.program );
65 glEnableVertexAttribArray( shaders.smooth.vertex );
66 glEnableVertexAttribArray( shaders.smooth.vertex_colour );
67 gl_uniformMat4( shaders.smooth.projection, &projection );
68}
69
70void gl_endSmoothProgram()
71{
72 glDisableVertexAttribArray( shaders.smooth.vertex );
73 glDisableVertexAttribArray( shaders.smooth.vertex_colour );
74 glUseProgram( 0 );
75 gl_checkErr();
76}
77
87void gl_renderRect( double x, double y, double w, double h, const glColour *c )
88{
89 /* Set the vertex. */
90 mat4 projection = gl_view_matrix;
91 mat4_translate_scale_xy( &projection, x, y, w, h );
92
93 gl_renderRectH( &projection, c, 1 );
94}
95
105void gl_renderRectEmpty( double x, double y, double w, double h,
106 const glColour *c )
107{
108 mat4 projection = gl_view_matrix;
109 mat4_translate_scale_xy( &projection, x, y, w, h );
110
111 gl_renderRectH( &projection, c, 0 );
112}
113
121void gl_renderRectH( const mat4 *H, const glColour *c, int filled )
122{
123 gl_beginSolidProgram( *H, c );
124 if ( filled ) {
125 gl_vboActivateAttribOffset( gl_squareVBO, shaders.solid.vertex, 0, 2,
126 GL_FLOAT, 0 );
127 glDrawArrays( GL_TRIANGLE_STRIP, 0, 4 );
128 } else {
129 gl_vboActivateAttribOffset( gl_squareEmptyVBO, shaders.solid.vertex, 0, 2,
130 GL_FLOAT, 0 );
131 glDrawArrays( GL_LINE_STRIP, 0, 5 );
132 }
133 gl_endSolidProgram();
134}
135
144void gl_renderCross( double x, double y, double r, const glColour *c )
145{
146 glUseProgram( shaders.crosshairs.program );
147 glUniform1f( shaders.crosshairs.paramf, 1. ); /* No outline. */
148 gl_renderShader( x, y, r, r, 0., &shaders.crosshairs, c, 1 );
149}
150
162void gl_renderTriangleEmpty( double x, double y, double a, double s,
163 double length, const glColour *c )
164{
165 mat4 projection = gl_view_matrix;
166 mat4_translate_xy( &projection, x, y );
167 if ( a != 0. )
168 mat4_rotate2d( &projection, a );
169 mat4_scale_xy( &projection, s * length, s );
170
171 gl_beginSolidProgram( projection, c );
172 gl_vboActivateAttribOffset( gl_triangleVBO, shaders.solid.vertex, 0, 2,
173 GL_FLOAT, 0 );
174 glDrawArrays( GL_LINE_STRIP, 0, 4 );
175 gl_endSolidProgram();
176}
177
178void gl_renderDepthRawH( GLuint depth, const mat4 *projection,
179 const mat4 *tex_mat )
180{
181 /* Depth testing is required for depth writing. */
182 glEnable( GL_DEPTH_TEST );
183 glDepthFunc( GL_ALWAYS );
184 glColorMask( GL_FALSE, GL_FALSE, GL_FALSE,
185 GL_FALSE ); /* Don't draw colour. */
186
187 glUseProgram( shaders.texture_depth_only.program );
188
189 /* Bind the texture_depth_only. */
190 glBindTexture( GL_TEXTURE_2D, depth );
191
192 /* Set the vertex. */
193 glEnableVertexAttribArray( shaders.texture_depth_only.vertex );
194 gl_vboActivateAttribOffset( gl_squareVBO, shaders.texture_depth_only.vertex,
195 0, 2, GL_FLOAT, 0 );
196
197 /* Set shader uniforms. */
198 gl_uniformMat4( shaders.texture_depth_only.projection, projection );
199 gl_uniformMat4( shaders.texture_depth_only.tex_mat, tex_mat );
200
201 /* Draw. */
202 glDrawArrays( GL_TRIANGLE_STRIP, 0, 4 );
203
204 /* Clear state. */
205 glDisableVertexAttribArray( shaders.texture_depth_only.vertex );
206 glColorMask( GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE );
207 glDepthFunc( GL_LESS );
208 glDisable( GL_DEPTH_TEST );
209
210 /* anything failed? */
211 gl_checkErr();
212
213 glUseProgram( 0 );
214}
215
216void gl_renderDepthRaw( GLuint depth, uint8_t flags, double x, double y,
217 double w, double h, double tx, double ty, double tw,
218 double th, double angle )
219{
220 mat4 projection, tex_mat;
221
222 /* Set the vertex. */
223 projection = gl_view_matrix;
224 if ( angle == 0. ) {
225 mat4_translate_scale_xy( &projection, x, y, w, h );
226 } else {
227 double hw = w * 0.5;
228 double hh = h * 0.5;
229 mat4_translate_xy( &projection, x + hw, y + hh );
230 mat4_rotate2d( &projection, angle );
231 mat4_translate_scale_xy( &projection, -hw, -hh, w, h );
232 }
233
234 /* Set the texture. */
235 tex_mat = ( flags & OPENGL_TEX_VFLIP )
236 ? mat4_ortho( -1., 1., 2., 0., 1., -1. )
237 : mat4_identity();
238 mat4_translate_scale_xy( &tex_mat, tx, ty, tw, th );
239
240 gl_renderDepthRawH( depth, &projection, &tex_mat );
241}
242
243void gl_renderTextureDepthRawH( GLuint texture, GLuint depth,
244 const mat4 *projection, const mat4 *tex_mat,
245 const glColour *c )
246{
247 /* Depth testing is required for depth writing. */
248 glEnable( GL_DEPTH_TEST );
249 glDepthFunc( GL_ALWAYS );
250
251 glUseProgram( shaders.texture_depth.program );
252
253 /* Bind the texture_depth. */
254 glActiveTexture( GL_TEXTURE1 );
255 glBindTexture( GL_TEXTURE_2D, depth );
256 glActiveTexture( GL_TEXTURE0 );
257 glBindTexture( GL_TEXTURE_2D, texture );
258
259 /* Must have colour for now. */
260 if ( c == NULL )
261 c = &cWhite;
262
263 /* Set the vertex. */
264 glEnableVertexAttribArray( shaders.texture_depth.vertex );
265 gl_vboActivateAttribOffset( gl_squareVBO, shaders.texture_depth.vertex, 0, 2,
266 GL_FLOAT, 0 );
267
268 /* Set shader uniforms. */
269 gl_uniformColour( shaders.texture_depth.colour, c );
270 gl_uniformMat4( shaders.texture_depth.projection, projection );
271 gl_uniformMat4( shaders.texture_depth.tex_mat, tex_mat );
272 glUniform1i( shaders.texture_depth.depth, 1 );
273
274 /* Draw. */
275 glDrawArrays( GL_TRIANGLE_STRIP, 0, 4 );
276
277 /* Clear state. */
278 glDisableVertexAttribArray( shaders.texture_depth.vertex );
279 glDepthFunc( GL_LESS );
280 glDisable( GL_DEPTH_TEST );
281
282 /* anything failed? */
283 gl_checkErr();
284
285 glUseProgram( 0 );
286}
287
288void gl_renderTextureDepthRaw( GLuint texture, GLuint depth, uint8_t flags,
289 double x, double y, double w, double h,
290 double tx, double ty, double tw, double th,
291 const glColour *c, double angle )
292{
293 mat4 projection, tex_mat;
294
295 /* Set the vertex. */
296 projection = gl_view_matrix;
297 if ( angle == 0. ) {
298 mat4_translate_scale_xy( &projection, x, y, w, h );
299 } else {
300 double hw = w * 0.5;
301 double hh = h * 0.5;
302 mat4_translate_xy( &projection, x + hw, y + hh );
303 mat4_rotate2d( &projection, angle );
304 mat4_translate_scale_xy( &projection, -hw, -hh, w, h );
305 }
306
307 /* Set the texture. */
308 tex_mat = ( flags & OPENGL_TEX_VFLIP )
309 ? mat4_ortho( -1., 1., 2., 0., 1., -1. )
310 : mat4_identity();
311 mat4_translate_scale_xy( &tex_mat, tx, ty, tw, th );
312
313 gl_renderTextureDepthRawH( texture, depth, &projection, &tex_mat, c );
314}
315
324void gl_renderTextureRawH( GLuint texture, const mat4 *projection,
325 const mat4 *tex_mat, const glColour *c )
326{
327 glUseProgram( shaders.texture.program );
328
329 /* Bind the texture. */
330 glBindTexture( GL_TEXTURE_2D, texture );
331
332 /* Must have colour for now. */
333 if ( c == NULL )
334 c = &cWhite;
335
336 /* Set the vertex. */
337 glEnableVertexAttribArray( shaders.texture.vertex );
338 gl_vboActivateAttribOffset( gl_squareVBO, shaders.texture.vertex, 0, 2,
339 GL_FLOAT, 0 );
340
341 /* Set shader uniforms. */
342 gl_uniformColour( shaders.texture.colour, c );
343 gl_uniformMat4( shaders.texture.projection, projection );
344 gl_uniformMat4( shaders.texture.tex_mat, tex_mat );
345
346 /* Draw. */
347 glDrawArrays( GL_TRIANGLE_STRIP, 0, 4 );
348
349 /* Clear state. */
350 glDisableVertexAttribArray( shaders.texture.vertex );
351
352 /* anything failed? */
353 gl_checkErr();
354
355 glUseProgram( 0 );
356}
357
374void gl_renderTextureRaw( GLuint texture, uint8_t flags, double x, double y,
375 double w, double h, double tx, double ty, double tw,
376 double th, const glColour *c, double angle )
377{
378 mat4 projection, tex_mat;
379
380 /* Set the vertex. */
381 projection = gl_view_matrix;
382 if ( angle == 0. ) {
383 mat4_translate_scale_xy( &projection, x, y, w, h );
384 } else {
385 double hw, hh; /* Half width and height. */
386 hw = w * 0.5;
387 hh = h * 0.5;
388 mat4_translate_xy( &projection, x + hw, y + hh );
389 mat4_rotate2d( &projection, angle );
390 mat4_translate_scale_xy( &projection, -hw, -hh, w, h );
391 }
392
393 /* Set the texture. */
394 tex_mat = ( flags & OPENGL_TEX_VFLIP )
395 ? mat4_ortho( -1., 1., 2., 0., 1., -1. )
396 : mat4_identity();
397 mat4_translate_scale_xy( &tex_mat, tx, ty, tw, th );
398
399 gl_renderTextureRawH( texture, &projection, &tex_mat, c );
400}
401
417void gl_renderTexture( const glTexture *texture, double x, double y, double w,
418 double h, double tx, double ty, double tw, double th,
419 const glColour *c, double angle )
420{
421 gl_renderTextureRaw( texture->texture, texture->flags, x, y, w, h, tx, ty,
422 tw, th, c, angle );
423}
424
437void gl_renderSDF( const glTexture *texture, double x, double y, double w,
438 double h, const glColour *c, double angle, double outline )
439{
440 (void)outline; /* TODO handle outline. */
441 double hw, hh; /* Half width and height */
442 double sw, sh;
443 mat4 projection, tex_mat;
444
445 glUseProgram( shaders.texturesdf.program );
446
447 /* Bind the texture. */
448 glBindTexture( GL_TEXTURE_2D, texture->texture );
449
450 /* Must have colour for now. */
451 if ( c == NULL )
452 c = &cWhite;
453
454 hw = w * 0.5;
455 hh = h * 0.5;
456
457 /* Set the vertex. */
458 projection = gl_view_matrix;
459 if ( angle == 0. ) {
460 mat4_translate_scale_xy( &projection, x + hw, y + hh, hw, hh );
461 } else {
462 mat4_translate_xy( &projection, x + hw, y + hh );
463 mat4_rotate2d( &projection, angle );
464 mat4_scale_xy( &projection, hw, hh );
465 }
466 glEnableVertexAttribArray( shaders.texturesdf.vertex );
467 gl_vboActivateAttribOffset( gl_circleVBO, shaders.texturesdf.vertex, 0, 2,
468 GL_FLOAT, 0 );
469
470 /* Set the texture. */
471 /* TODO we would want to pad the texture a bit to get nice marked borders,
472 * but we have to actually pad the SDF first... */
473 sw = 0.; // 1./w;
474 sh = 0.; // 1./h;
475 tex_mat = ( texture->flags & OPENGL_TEX_VFLIP )
476 ? mat4_ortho( -1., 1., 2., 0., 1., -1. )
477 : mat4_identity();
478 mat4_scale_xy( &tex_mat, texture->srw + 2. * sw, texture->srh + 2. * sh );
479 mat4_translate_xy( &tex_mat, -sw, -sh );
480
481 /* Set shader uniforms. */
482 gl_uniformColour( shaders.texturesdf.colour, c );
483 gl_uniformMat4( shaders.texturesdf.projection, &projection );
484 gl_uniformMat4( shaders.texturesdf.tex_mat, &tex_mat );
485 glUniform1f( shaders.texturesdf.m,
486 ( 2.0 * texture->vmax * ( w + 2. ) / texture->w ) );
487
488 /* Draw. */
489 glDrawArrays( GL_TRIANGLE_STRIP, 0, 4 );
490
491 /* Clear state. */
492 glDisableVertexAttribArray( shaders.texturesdf.vertex );
493
494 /* anything failed? */
495 gl_checkErr();
496
497 glUseProgram( 0 );
498}
499
510void gl_renderTextureInterpolateRawH( GLuint ta, GLuint tb, double inter,
511 const mat4 *projection,
512 const mat4 *tex_mat, const glColour *c )
513{
514 /* Corner cases. */
515 if ( inter >= 1. )
516 return gl_renderTextureRawH( ta, projection, tex_mat, c );
517 else if ( inter <= 0. )
518 return gl_renderTextureRawH( tb, projection, tex_mat, c );
519
520 /* Must have colour for now. */
521 if ( c == NULL )
522 c = &cWhite;
523
524 glUseProgram( shaders.texture_interpolate.program );
525
526 /* Bind the textures. */
527 glActiveTexture( GL_TEXTURE1 );
528 glBindTexture( GL_TEXTURE_2D, tb );
529 glActiveTexture( GL_TEXTURE0 );
530 glBindTexture( GL_TEXTURE_2D, ta );
531 /* Always end with TEXTURE0 active. */
532
533 /* Set the vertex. */
534 glEnableVertexAttribArray( shaders.texture_interpolate.vertex );
535 gl_vboActivateAttribOffset( gl_squareVBO, shaders.texture_interpolate.vertex,
536 0, 2, GL_FLOAT, 0 );
537
538 /* Set shader uniforms. */
539 glUniform1i( shaders.texture_interpolate.sampler1, 0 );
540 glUniform1i( shaders.texture_interpolate.sampler2, 1 );
541 gl_uniformColour( shaders.texture_interpolate.colour, c );
542 glUniform1f( shaders.texture_interpolate.inter, inter );
543 gl_uniformMat4( shaders.texture_interpolate.projection, projection );
544 gl_uniformMat4( shaders.texture_interpolate.tex_mat, tex_mat );
545
546 /* Draw. */
547 glDrawArrays( GL_TRIANGLE_STRIP, 0, 4 );
548
549 /* Clear state. */
550 glDisableVertexAttribArray( shaders.texture_interpolate.vertex );
551
552 /* anything failed? */
553 gl_checkErr();
554
555 glUseProgram( 0 );
556}
557
577 double inter, double x, double y, double w,
578 double h, double tx, double ty, double tw,
579 double th, const glColour *c )
580{
581 mat4 projection, tex_mat;
582
583 /* Case no need for interpolation. */
584 if ( tb == NULL )
585 return gl_renderTexture( ta, x, y, w, h, tx, ty, tw, th, c, 0. );
586 else if ( ta == NULL )
587 return gl_renderTexture( tb, x, y, w, h, tx, ty, tw, th, c, 0. );
588
589 projection = gl_view_matrix;
590 mat4_translate_scale_xy( &projection, x, y, w, h );
591 tex_mat = ( ta->flags & OPENGL_TEX_VFLIP )
592 ? mat4_ortho( -1., 1., 2., 0., 1., -1. )
593 : mat4_identity();
594 mat4_translate_scale_xy( &tex_mat, tx, ty, tw, th );
595
596 return gl_renderTextureInterpolateRawH( ta->texture, tb->texture, inter,
597 &projection, &tex_mat, c );
598}
599
608void gl_gameToScreenCoords( double *nx, double *ny, double bx, double by )
609{
610 double cx, cy, gx, gy, z;
611
612 /* Get parameters. */
613 cam_getPos( &cx, &cy );
614 z = cam_getZoom();
615 gui_getOffset( &gx, &gy );
616
617 /* calculate position - we'll use relative coords to player */
618 *nx = ( bx - cx ) * z + gx + SCREEN_W * 0.5;
619 *ny = ( by - cy ) * z + gy + SCREEN_H * 0.5;
620}
621
629{
630 double cx, cy, gx, gy, z;
631 mat4 projection = lhs;
632
633 /* Get parameters. */
634 cam_getPos( &cx, &cy );
635 z = cam_getZoom();
636 gui_getOffset( &gx, &gy );
637
638 mat4_translate_scale_xy( &projection, gx + SCREEN_W * 0.5,
639 gy + SCREEN_H * 0.5, z, z );
640 mat4_translate_xy( &projection, -cx, cy );
641 return projection;
642}
643
652void gl_screenToGameCoords( double *nx, double *ny, int bx, int by )
653{
654 double cx, cy, gx, gy, z;
655
656 /* Get parameters. */
657 cam_getPos( &cx, &cy );
658 z = cam_getZoom();
659 gui_getOffset( &gx, &gy );
660
661 /* calculate position - we'll use relative coords to player */
662 *nx = ( bx - SCREEN_W * 0.5 - gx ) / z + cx;
663 *ny = ( by - SCREEN_H * 0.5 - gy ) / z + cy;
664}
665
679void gl_renderSprite( const glTexture *sprite, double bx, double by, int sx,
680 int sy, const glColour *c )
681{
682 double x, y, w, h, tx, ty, z;
683
684 /* Translate coords. */
685 z = cam_getZoom();
686 gl_gameToScreenCoords( &x, &y, bx - sprite->sw * 0.5,
687 by - sprite->sh * 0.5 );
688
689 /* Scaled sprite dimensions. */
690 w = sprite->sw * z;
691 h = sprite->sh * z;
692
693 /* check if inbounds */
694 if ( ( x < -w ) || ( x > SCREEN_W + w ) || ( y < -h ) ||
695 ( y > SCREEN_H + h ) )
696 return;
697
698 /* texture coords */
699 tx = sprite->sw * (double)( sx ) / sprite->w;
700 ty = sprite->sh * ( sprite->sy - (double)sy - 1 ) / sprite->h;
701
702 gl_renderTexture( sprite, x, y, w, h, tx, ty, sprite->srw, sprite->srh, c,
703 0. );
704}
705
721void gl_renderSpriteScale( const glTexture *sprite, double bx, double by,
722 double scalew, double scaleh, int sx, int sy,
723 const glColour *c )
724{
725 double x, y, w, h, tx, ty, z;
726
727 /* Translate coords. */
728 z = cam_getZoom();
729 gl_gameToScreenCoords( &x, &y, bx - sprite->sw * 0.5,
730 by - sprite->sh * 0.5 );
731
732 /* Scaled sprite dimensions. */
733 w = sprite->sw * z * scalew;
734 h = sprite->sh * z * scaleh;
735
736 /* check if inbounds */
737 if ( ( x < -w ) || ( x > SCREEN_W + w ) || ( y < -h ) ||
738 ( y > SCREEN_H + h ) )
739 return;
740
741 /* texture coords */
742 tx = sprite->sw * (double)( sx ) / sprite->w;
743 ty = sprite->sh * ( sprite->sy - (double)sy - 1 ) / sprite->h;
744
745 gl_renderTexture( sprite, x, y, w, h, tx, ty, sprite->srw, sprite->srh, c,
746 0. );
747}
748
763void gl_renderSpriteRotate( const glTexture *sprite, double bx, double by,
764 double angle, int sx, int sy, const glColour *c )
765{
766 double x, y, w, h, tx, ty, z;
767
768 /* Translate coords. */
769 z = cam_getZoom();
770 gl_gameToScreenCoords( &x, &y, bx - sprite->sw * 0.5,
771 by - sprite->sh * 0.5 );
772
773 /* Scaled sprite dimensions. */
774 w = sprite->sw * z;
775 h = sprite->sh * z;
776
777 /* check if inbounds */
778 if ( ( x < -w ) || ( x > SCREEN_W + w ) || ( y < -h ) ||
779 ( y > SCREEN_H + h ) )
780 return;
781
782 /* texture coords */
783 tx = sprite->sw * (double)( sx ) / sprite->w;
784 ty = sprite->sh * ( sprite->sy - (double)sy - 1 ) / sprite->h;
785
786 gl_renderTexture( sprite, x, y, w, h, tx, ty, sprite->srw, sprite->srh, c,
787 angle );
788}
789
807void gl_renderSpriteScaleRotate( const glTexture *sprite, double bx, double by,
808 double scalew, double scaleh, double angle,
809 int sx, int sy, const glColour *c )
810{
811 double x, y, w, h, tx, ty, z;
812
813 /* Translate coords. */
814 z = cam_getZoom();
815 gl_gameToScreenCoords( &x, &y, bx - sprite->sw * 0.5,
816 by - sprite->sh * 0.5 );
817
818 /* Scaled sprite dimensions. */
819 w = sprite->sw * z * scalew;
820 h = sprite->sh * z * scaleh;
821
822 /* check if inbounds */
823 if ( ( x < -w ) || ( x > SCREEN_W + w ) || ( y < -h ) ||
824 ( y > SCREEN_H + h ) )
825 return;
826
827 /* texture coords */
828 tx = sprite->sw * (double)( sx ) / sprite->w;
829 ty = sprite->sh * ( sprite->sy - (double)sy - 1 ) / sprite->h;
830
831 gl_renderTexture( sprite, x, y, w, h, tx, ty, sprite->srw, sprite->srh, c,
832 angle );
833}
834
853 double inter, double bx, double by, int sx,
854 int sy, const glColour *c )
855{
856 gl_renderSpriteInterpolateScale( sa, sb, inter, bx, by, 1., 1., sx, sy, c );
857}
858
879 double inter, double bx, double by,
880 double scalew, double scaleh, int sx,
881 int sy, const glColour *c )
882{
883 double x, y, w, h, tx, ty, z;
884
885 /* Translate coords. */
886 gl_gameToScreenCoords( &x, &y, bx - scalew * sa->sw * 0.5,
887 by - scaleh * sa->sh * 0.5 );
888
889 /* Scaled sprite dimensions. */
890 z = cam_getZoom();
891 w = sa->sw * z * scalew;
892 h = sa->sh * z * scaleh;
893
894 /* check if inbounds */
895 if ( ( x < -w ) || ( x > SCREEN_W + w ) || ( y < -h ) ||
896 ( y > SCREEN_H + h ) )
897 return;
898
899 /* texture coords */
900 tx = sa->sw * (double)( sx ) / sa->w;
901 ty = sa->sh * ( sa->sy - (double)sy - 1 ) / sa->h;
902
903 gl_renderTextureInterpolate( sa, sb, inter, x, y, w, h, tx, ty, sa->srw,
904 sa->srh, c );
905}
906
917void gl_renderStaticSprite( const glTexture *sprite, double bx, double by,
918 int sx, int sy, const glColour *c )
919{
920 double x, y, tx, ty;
921
922 x = bx;
923 y = by;
924
925 /* texture coords */
926 tx = sprite->sw * (double)( sx ) / sprite->w;
927 ty = sprite->sh * ( sprite->sy - (double)sy - 1 ) / sprite->h;
928
929 /* actual blitting */
930 gl_renderTexture( sprite, x, y, sprite->sw, sprite->sh, tx, ty, sprite->srw,
931 sprite->srh, c, 0. );
932}
933
952 double inter, double bx, double by,
953 int sx, int sy, const glColour *c )
954{
955 gl_renderStaticSpriteInterpolateScale( sa, sb, inter, bx, by, 1., 1., sx, sy,
956 c );
957}
958
979 const glTexture *sb, double inter,
980 double bx, double by, double scalew,
981 double scaleh, int sx, int sy,
982 const glColour *c )
983{
984 double x, y, w, h, tx, ty;
985
986 x = bx;
987 y = by;
988
989 /* Scaled sprite dimensions. */
990 w = sa->sw * scalew;
991 h = sa->sh * scaleh;
992
993 /* check if inbounds */
994 if ( ( x < -w ) || ( x > SCREEN_W + w ) || ( y < -h ) ||
995 ( y > SCREEN_H + h ) )
996 return;
997
998 /* texture coords */
999 tx = sa->sw * (double)( sx ) / sa->w;
1000 ty = sa->sh * ( sa->sy - (double)sy - 1 ) / sa->h;
1001
1002 gl_renderTextureInterpolate( sa, sb, inter, x, y, w, h, tx, ty, sa->srw,
1003 sa->srh, c );
1004}
1005
1018void gl_renderScaleSprite( const glTexture *sprite, double bx, double by,
1019 int sx, int sy, double bw, double bh,
1020 const glColour *c )
1021{
1022 double x, y, tx, ty;
1023
1024 x = bx;
1025 y = by;
1026
1027 /* texture coords */
1028 tx = sprite->sw * (double)( sx ) / sprite->w;
1029 ty = sprite->sh * ( sprite->sy - (double)sy - 1 ) / sprite->h;
1030
1031 /* actual blitting */
1032 gl_renderTexture( sprite, x, y, bw, bh, tx, ty, sprite->srw, sprite->srh, c,
1033 0. );
1034}
1035
1046void gl_renderScale( const glTexture *texture, double bx, double by, double bw,
1047 double bh, const glColour *c )
1048{
1049 double x, y, tx, ty;
1050
1051 /* here we use absolute coords */
1052 x = bx;
1053 y = by;
1054
1055 /* texture dimensions */
1056 tx = ty = 0.;
1057
1058 /* Actual blitting. */
1059 gl_renderTexture( texture, x, y, bw, bh, tx, ty, texture->srw, texture->srh,
1060 c, 0. );
1061}
1062
1074void gl_renderScaleAspect( const glTexture *texture, double bx, double by,
1075 double bw, double bh, const glColour *c )
1076{
1077 double scale;
1078 double nw, nh;
1079
1080 scale = MIN( bw / texture->w, bh / texture->h );
1081
1082 nw = scale * texture->w;
1083 nh = scale * texture->h;
1084
1085 bx += ( bw - nw ) * 0.5;
1086 by += ( bh - nh ) * 0.5;
1087
1088 gl_renderScale( texture, bx, by, nw, nh, c );
1089}
1090
1099void gl_renderStatic( const glTexture *texture, double bx, double by,
1100 const glColour *c )
1101{
1102 double x, y;
1103
1104 /* here we use absolute coords */
1105 x = bx;
1106 y = by;
1107
1108 /* actual blitting */
1109 gl_renderTexture( texture, x, y, texture->sw, texture->sh, 0., 0.,
1110 texture->srw, texture->srh, c, 0. );
1111}
1112
1126void gl_renderShader( double x, double y, double w, double h, double r,
1127 const SimpleShader *shd, const glColour *c, int center )
1128{
1129 mat4 projection = gl_view_matrix;
1130 mat4_translate_xy( &projection, x, y );
1131 if ( r != 0. )
1132 mat4_rotate2d( &projection, r );
1133 mat4_scale_xy( &projection, w, h );
1134 glUniform2f( shd->dimensions, w, h );
1135 gl_renderShaderH( shd, &projection, c, center );
1136}
1137
1147void gl_renderShaderH( const SimpleShader *shd, const mat4 *H,
1148 const glColour *c, int center )
1149{
1150 glEnableVertexAttribArray( shd->vertex );
1151 gl_vboActivateAttribOffset( center ? gl_circleVBO : gl_squareVBO,
1152 shd->vertex, 0, 2, GL_FLOAT, 0 );
1153
1154 if ( c != NULL )
1155 gl_uniformColour( shd->colour, c );
1156
1157 gl_uniformMat4( shd->projection, H );
1158
1159 glDrawArrays( GL_TRIANGLE_STRIP, 0, 4 );
1160
1161 glDisableVertexAttribArray( shd->vertex );
1162 glUseProgram( 0 );
1163 gl_checkErr();
1164}
1165
1175void gl_renderCircle( double cx, double cy, double r, const glColour *c,
1176 int filled )
1177{
1178 /* Set the vertex. */
1179 mat4 projection = gl_view_matrix;
1180 mat4_translate_scale_xy( &projection, cx, cy, r, r );
1181
1182 /* Draw! */
1183 gl_renderCircleH( &projection, c, filled );
1184}
1185
1193void gl_renderCircleH( const mat4 *H, const glColour *c, int filled )
1194{
1195 // TODO handle shearing and different x/y scaling
1196 GLfloat r = H->m[0][0] / gl_view_matrix.m[0][0];
1197
1198 glUseProgram( shaders.circle.program );
1199 glUniform2f( shaders.circle.dimensions, r, r );
1200 glUniform1i( shaders.circle.parami, filled );
1201 gl_renderShaderH( &shaders.circle, H, c, 1 );
1202}
1203
1213void gl_renderLine( double x1, double y1, double x2, double y2,
1214 const glColour *c )
1215{
1216 double a = atan2( y2 - y1, x2 - x1 );
1217 double s = hypotf( x2 - x1, y2 - y1 );
1218
1219 glUseProgram( shaders.sdfsolid.program );
1220 glUniform1f( shaders.sdfsolid.paramf, 1. ); /* No outline. */
1221 gl_renderShader( ( x1 + x2 ) * 0.5, ( y1 + y2 ) * 0.5, s * 0.5 + 0.5, 1.0, a,
1222 &shaders.sdfsolid, c, 1 );
1223}
1224
1233void gl_clipRect( int x, int y, int w, int h )
1234{
1235 double rx, ry, rw, rh;
1236 rx = ( x + gl_screen.x ) / gl_screen.mxscale;
1237 ry = ( y + gl_screen.y ) / gl_screen.myscale;
1238 rw = w / gl_screen.mxscale;
1239 rh = h / gl_screen.myscale;
1240 glScissor( rx, ry, rw, rh );
1241 glEnable( GL_SCISSOR_TEST );
1242}
1243
1247void gl_unclipRect( void )
1248{
1249 glDisable( GL_SCISSOR_TEST );
1250 glScissor( 0, 0, gl_screen.rw, gl_screen.rh );
1251}
1252
1258int gl_initRender( void )
1259{
1260 GLfloat vertex[10];
1261
1262 /* Initialize the VBO. */
1264 sizeof( GLfloat ) * OPENGL_RENDER_VBO_SIZE * ( 2 + 2 + 4 ), NULL );
1265 gl_renderVBOtexOffset = sizeof( GLfloat ) * OPENGL_RENDER_VBO_SIZE * 2;
1267 sizeof( GLfloat ) * OPENGL_RENDER_VBO_SIZE * ( 2 + 2 );
1268
1269 vertex[0] = 0.;
1270 vertex[1] = 0.;
1271 vertex[2] = 1.;
1272 vertex[3] = 0.;
1273 vertex[4] = 0.;
1274 vertex[5] = 1.;
1275 vertex[6] = 1.;
1276 vertex[7] = 1.;
1277 gl_squareVBO = gl_vboCreateStatic( sizeof( GLfloat ) * 8, vertex );
1278
1279 vertex[0] = -1.;
1280 vertex[1] = -1.;
1281 vertex[2] = 1.;
1282 vertex[3] = -1.;
1283 vertex[4] = -1.;
1284 vertex[5] = 1.;
1285 vertex[6] = 1.;
1286 vertex[7] = 1.;
1287 gl_circleVBO = gl_vboCreateStatic( sizeof( GLfloat ) * 8, vertex );
1288
1289 vertex[0] = 0.;
1290 vertex[1] = 0.;
1291 vertex[2] = 1.;
1292 vertex[3] = 0.;
1293 vertex[4] = 1.;
1294 vertex[5] = 1.;
1295 vertex[6] = 0.;
1296 vertex[7] = 1.;
1297 vertex[8] = 0.;
1298 vertex[9] = 0.;
1299 gl_squareEmptyVBO = gl_vboCreateStatic( sizeof( GLfloat ) * 8, vertex );
1300
1301 vertex[0] = 0.;
1302 vertex[1] = 0.;
1303 vertex[2] = 1.;
1304 vertex[3] = 0.;
1305 gl_lineVBO = gl_vboCreateStatic( sizeof( GLfloat ) * 4, vertex );
1306
1307 vertex[0] = 0.5 * cos( 4. * M_PI / 3. );
1308 vertex[1] = 0.5 * sin( 4. * M_PI / 3. );
1309 vertex[2] = 0.5 * cos( 0. );
1310 vertex[3] = 0.5 * sin( 0. );
1311 vertex[4] = 0.5 * cos( 2. * M_PI / 3. );
1312 vertex[5] = 0.5 * sin( 2. * M_PI / 3. );
1313 vertex[6] = vertex[0];
1314 vertex[7] = vertex[1];
1315 gl_triangleVBO = gl_vboCreateStatic( sizeof( GLfloat ) * 8, vertex );
1316
1317 gl_checkErr();
1318
1319 return 0;
1320}
1321
1325void gl_exitRender( void )
1326{
1327 /* Destroy the VBO. */
1329 gl_vboDestroy( gl_squareVBO );
1330 gl_vboDestroy( gl_circleVBO );
1331 gl_vboDestroy( gl_squareEmptyVBO );
1332 gl_vboDestroy( gl_lineVBO );
1333 gl_vboDestroy( gl_triangleVBO );
1334 gl_renderVBO = NULL;
1335}
void cam_getPos(double *x, double *y)
Gets the camera position.
Definition camera.c:122
double cam_getZoom(void)
Gets the camera zoom.
Definition camera.c:101
void gui_getOffset(double *x, double *y)
Gets the GUI offset.
Definition gui.c:2159
mat4 mat4_identity(void)
Creates an identity matrix.
Definition mat4.c:335
mat4 mat4_ortho(double left, double right, double bottom, double top, double nearVal, double farVal)
Creates an orthographic projection matrix.
Definition mat4.c:347
void mat4_rotate2d(mat4 *m, double angle)
Rotates an angle, in radians, around the z axis.
Definition mat4.c:167
Header file with generic functions and naev-specifics.
#define MIN(x, y)
Definition naev.h:39
glInfo gl_screen
Definition opengl.c:47
void gl_exitRender(void)
Cleans up the OpenGL rendering routines.
void gl_renderShader(double x, double y, double w, double h, double r, const SimpleShader *shd, const glColour *c, int center)
Renders a simple shader.
void gl_renderShaderH(const SimpleShader *shd, const mat4 *H, const glColour *c, int center)
Renders a simple shader with a transformation.
static int gl_renderVBOcolOffset
void gl_renderRect(double x, double y, double w, double h, const glColour *c)
Renders a rectangle.
void gl_renderLine(double x1, double y1, double x2, double y2, const glColour *c)
Draws a line.
void gl_gameToScreenCoords(double *nx, double *ny, double bx, double by)
Converts in-game coordinates to screen coordinates.
#define OPENGL_RENDER_VBO_SIZE
void gl_renderSpriteInterpolate(const glTexture *sa, const glTexture *sb, double inter, double bx, double by, int sx, int sy, const glColour *c)
Blits a sprite interpolating, position is relative to the player.
int gl_initRender(void)
Initializes the OpenGL rendering routines.
void gl_renderCircleH(const mat4 *H, const glColour *c, int filled)
Draws a circle.
void gl_renderTexture(const glTexture *texture, double x, double y, double w, double h, double tx, double ty, double tw, double th, const glColour *c, double angle)
Texture blitting backend.
void gl_renderTriangleEmpty(double x, double y, double a, double s, double length, const glColour *c)
Renders a triangle at a given position.
void gl_unclipRect(void)
Clears the 2d clipping planes.
static int gl_renderVBOtexOffset
void gl_renderSpriteScale(const glTexture *sprite, double bx, double by, double scalew, double scaleh, int sx, int sy, const glColour *c)
Blits a sprite, position is relative to the player.
void gl_renderSpriteScaleRotate(const glTexture *sprite, double bx, double by, double scalew, double scaleh, double angle, int sx, int sy, const glColour *c)
Blits a sprite, position is relative to the player with scaling and rotation.
void gl_renderStatic(const glTexture *texture, double bx, double by, const glColour *c)
Blits a texture to a position.
void gl_renderSDF(const glTexture *texture, double x, double y, double w, double h, const glColour *c, double angle, double outline)
SDF Texture blitting backend.
void gl_renderScale(const glTexture *texture, double bx, double by, double bw, double bh, const glColour *c)
Blits a texture scaling it.
void gl_renderScaleSprite(const glTexture *sprite, double bx, double by, int sx, int sy, double bw, double bh, const glColour *c)
Blits a scaled sprite, position is in absolute screen coordinates.
void gl_renderTextureInterpolate(const glTexture *ta, const glTexture *tb, double inter, double x, double y, double w, double h, double tx, double ty, double tw, double th, const glColour *c)
Texture blitting backend for interpolated texture.
void gl_renderScaleAspect(const glTexture *texture, double bx, double by, double bw, double bh, const glColour *c)
Blits a texture scaling it to fit a rectangle, but conserves aspect ratio.
void gl_renderTextureRaw(GLuint texture, uint8_t flags, double x, double y, double w, double h, double tx, double ty, double tw, double th, const glColour *c, double angle)
Texture blitting backend.
void gl_renderSprite(const glTexture *sprite, double bx, double by, int sx, int sy, const glColour *c)
Blits a sprite, position is relative to the player.
void gl_renderStaticSpriteInterpolate(const glTexture *sa, const glTexture *sb, double inter, double bx, double by, int sx, int sy, const glColour *c)
Blits a sprite interpolating, position is relative to the player.
void gl_screenToGameCoords(double *nx, double *ny, int bx, int by)
Converts screen coordinates to in-game coordinates.
void gl_renderStaticSprite(const glTexture *sprite, double bx, double by, int sx, int sy, const glColour *c)
Blits a sprite, position is in absolute screen coordinates.
void gl_renderTextureRawH(GLuint texture, const mat4 *projection, const mat4 *tex_mat, const glColour *c)
Texture blitting backend.
static gl_vbo * gl_renderVBO
void gl_renderRectEmpty(double x, double y, double w, double h, const glColour *c)
Renders a rectangle.
void gl_renderCross(double x, double y, double r, const glColour *c)
Renders a cross at a given position.
void gl_renderSpriteRotate(const glTexture *sprite, double bx, double by, double angle, int sx, int sy, const glColour *c)
Blits a sprite, position is relative to the player with rotation.
void gl_renderTextureInterpolateRawH(GLuint ta, GLuint tb, double inter, const mat4 *projection, const mat4 *tex_mat, const glColour *c)
Texture blitting backend for interpolated texture.
void gl_renderStaticSpriteInterpolateScale(const glTexture *sa, const glTexture *sb, double inter, double bx, double by, double scalew, double scaleh, int sx, int sy, const glColour *c)
Blits a sprite interpolating, position is relative to the player.
void gl_renderSpriteInterpolateScale(const glTexture *sa, const glTexture *sb, double inter, double bx, double by, double scalew, double scaleh, int sx, int sy, const glColour *c)
Blits a sprite interpolating, position is relative to the player.
void gl_renderRectH(const mat4 *H, const glColour *c, int filled)
Renders a rectangle.
mat4 gl_gameToScreenMatrix(mat4 lhs)
Return a transformation which converts in-game coordinates to screen coordinates.
void gl_clipRect(int x, int y, int w, int h)
Sets up 2d clipping planes around a rectangle.
void gl_renderCircle(double cx, double cy, double r, const glColour *c, int filled)
Draws a circle.
void gl_vboDestroy(gl_vbo *vbo)
Destroys a VBO.
Definition opengl_vbo.c:244
gl_vbo * gl_vboCreateStream(GLsizei size, const void *data)
Creates a stream vbo.
Definition opengl_vbo.c:143
void gl_vboActivateAttribOffset(gl_vbo *vbo, GLuint index, GLuint offset, GLint size, GLenum type, GLsizei stride)
Activates a VBO's offset.
Definition opengl_vbo.c:224
gl_vbo * gl_vboCreateStatic(GLsizei size, const void *data)
Creates a stream vbo.
Definition opengl_vbo.c:177
static const double c[]
Definition rng.c:256
Abstraction for rendering sprite sheets.
Definition opengl_tex.h:43
double sw
Definition opengl_tex.h:53
double sh
Definition opengl_tex.h:54
double w
Definition opengl_tex.h:47
uint8_t flags
Definition opengl_tex.h:64
double srh
Definition opengl_tex.h:56
GLuint texture
Definition opengl_tex.h:59
double sy
Definition opengl_tex.h:52
double h
Definition opengl_tex.h:48
double srw
Definition opengl_tex.h:55
Definition mat4.h:12