/** * @brief Sets the opengl viewport. */ void gl_viewport( int x, int y, int w, int h ) { gl_matrixMode(GL_PROJECTION); gl_matrixIdentity(); gl_matrixOrtho( 0., /* Left edge. */ gl_screen.nw, /* Right edge. */ 0., /* Bottom edge. */ gl_screen.nh, /* Top edge. */ -1., /* near */ 1. ); /* far */ /* Take into account possible translation. */ gl_screen.x = x; gl_screen.y = y; gl_matrixTranslate( x, y ); /* Set screen size. */ gl_screen.w = w; gl_screen.h = h; /* Take into account possible scaling. */ if (gl_screen.scale != 1.) gl_matrixScale( gl_screen.wscale, gl_screen.hscale ); }
/** * @brief Renders the nebula overlay (hides what player can't see). * * @param dt Current delta tick. */ void nebu_renderOverlay( const double dt ) { (void) dt; double gx, gy; double ox, oy; double z; double sx, sy; /* Get GUI offsets. */ gui_getOffset( &gx, &gy ); /* Get zoom. */ z = cam_getZoom(); /* * Renders the puffs */ nebu_renderPuffs( 0 ); /* Prepare the matrix */ ox = gx; oy = gy; spfx_getShake( &sx, &sy ); ox += sx; oy += sy; gl_matrixPush(); gl_matrixTranslate( SCREEN_W/2.+ox, SCREEN_H/2.+oy ); gl_matrixScale( z, z ); /* * Mask for area player can still see (partially) */ glShadeModel(GL_SMOOTH); gl_vboActivateOffset( nebu_vboOverlay, GL_VERTEX_ARRAY, 0, 2, GL_FLOAT, 0 ); gl_vboActivateOffset( nebu_vboOverlay, GL_COLOR_ARRAY, sizeof(GLfloat)*2*18, 4, GL_FLOAT, 0 ); glDrawArrays( GL_TRIANGLE_FAN, 0, 18 ); /* * Solid nebula for areas the player can't see */ glShadeModel(GL_FLAT); /* Colour is shared. */ gl_vboActivateOffset( nebu_vboOverlay, GL_COLOR_ARRAY, sizeof(GLfloat)*((2+4)*18 + 2*28), 4, GL_FLOAT, 0 ); /* Top left. */ gl_vboActivateOffset( nebu_vboOverlay, GL_VERTEX_ARRAY, sizeof(GLfloat)*((2+4)*18 + 0*2*7), 2, GL_FLOAT, 0 ); glDrawArrays( GL_TRIANGLE_FAN, 0, 7 ); /* Top right. */ gl_vboActivateOffset( nebu_vboOverlay, GL_VERTEX_ARRAY, sizeof(GLfloat)*((2+4)*18 + 1*2*7), 2, GL_FLOAT, 0 ); glDrawArrays( GL_TRIANGLE_FAN, 0, 7 ); /* Bottom right. */ gl_vboActivateOffset( nebu_vboOverlay, GL_VERTEX_ARRAY, sizeof(GLfloat)*((2+4)*18 + 2*2*7), 2, GL_FLOAT, 0 ); glDrawArrays( GL_TRIANGLE_FAN, 0, 7 ); /* Bottom left. */ gl_vboActivateOffset( nebu_vboOverlay, GL_VERTEX_ARRAY, sizeof(GLfloat)*((2+4)*18 + 3*2*7), 2, GL_FLOAT, 0 ); glDrawArrays( GL_TRIANGLE_FAN, 0, 7 ); gl_vboDeactivate(); gl_matrixPop(); /* Reset puff movement. */ puff_x = 0.; puff_y = 0.; gl_checkErr(); }
/** * @brief Renders the starry background. * * @param dt Current delta tick. */ void background_renderStars( const double dt ) { (void) dt; unsigned int i; GLfloat hh, hw, h, w; GLfloat x, y, m, b; GLfloat brightness; double z; double sx, sy; int shade_mode; int j, n; /* * gprof claims it's the slowest thing in the game! */ /* Do some scaling for now. */ z = cam_getZoom(); z = 1. * (1. - conf.zoom_stars) + z * conf.zoom_stars; gl_matrixPush(); gl_matrixTranslate( SCREEN_W/2., SCREEN_H/2. ); gl_matrixScale( z, z ); if (!paused && (player.p != NULL) && !player_isFlag(PLAYER_DESTROYED) && !player_isFlag(PLAYER_CREATING)) { /* update position */ /* Calculate some dimensions. */ w = (SCREEN_W + 2.*STAR_BUF); w += conf.zoom_stars * (w / conf.zoom_far - 1.); h = (SCREEN_H + 2.*STAR_BUF); h += conf.zoom_stars * (h / conf.zoom_far - 1.); hw = w/2.; hh = h/2.; if ((star_x > SCREEN_W) || (star_y > SCREEN_H)) { sx = ceil( star_x / SCREEN_W ); sy = ceil( star_y / SCREEN_H ); n = MAX( sx, sy ); star_x /= (double)n; star_y /= (double)n; } else n = 1; /* Calculate new star positions. */ for (j=0; j < n; j++) { for (i=0; i < nstars; i++) { /* calculate new position */ b = 1./(9. - 10.*star_colour[8*i+3]); star_vertex[4*i+0] = star_vertex[4*i+0] + star_x*b; star_vertex[4*i+1] = star_vertex[4*i+1] + star_y*b; /* check boundaries */ if (star_vertex[4*i+0] > hw) star_vertex[4*i+0] -= w; else if (star_vertex[4*i+0] < -hw) star_vertex[4*i+0] += w; if (star_vertex[4*i+1] > hh) star_vertex[4*i+1] -= h; else if (star_vertex[4*i+1] < -hh) star_vertex[4*i+1] += h; } } /* Upload the data. */ gl_vboSubData( star_vertexVBO, 0, nstars * 4 * sizeof(GLfloat), star_vertex ); } /* Decide on shade mode. */ shade_mode = 0; if ((player.p != NULL) && !player_isFlag(PLAYER_DESTROYED) && !player_isFlag(PLAYER_CREATING)) { if (pilot_isFlag(player.p,PILOT_HYPERSPACE) && /* hyperspace fancy effects */ (player.p->ptimer < HYPERSPACE_STARS_BLUR)) { glShadeModel(GL_SMOOTH); shade_mode = 1; /* lines will be based on velocity */ m = HYPERSPACE_STARS_BLUR-player.p->ptimer; m /= HYPERSPACE_STARS_BLUR; m *= HYPERSPACE_STARS_LENGTH; x = m*cos(VANGLE(player.p->solid->vel)); y = m*sin(VANGLE(player.p->solid->vel)); } else if (dt_mod > 3.) { glShadeModel(GL_SMOOTH); shade_mode = 1; /* lines will be based on velocity */ m = (dt_mod-3.)*VMOD(player.p->solid->vel)/10.; x = m*cos(VANGLE(player.p->solid->vel)); y = m*sin(VANGLE(player.p->solid->vel)); } if (shade_mode) { /* Generate lines. */ for (i=0; i < nstars; i++) { brightness = star_colour[8*i+3]; star_vertex[4*i+2] = star_vertex[4*i+0] + x*brightness; star_vertex[4*i+3] = star_vertex[4*i+1] + y*brightness; } /* Upload new data. */ gl_vboSubData( star_vertexVBO, 0, nstars * 4 * sizeof(GLfloat), star_vertex ); } } /* Render. */ gl_vboActivate( star_vertexVBO, GL_VERTEX_ARRAY, 2, GL_FLOAT, 2 * sizeof(GLfloat) ); gl_vboActivate( star_colourVBO, GL_COLOR_ARRAY, 4, GL_FLOAT, 4 * sizeof(GLfloat) ); if (shade_mode) { glDrawArrays( GL_LINES, 0, nstars ); glDrawArrays( GL_POINTS, 0, nstars ); /* This second pass is when the lines are very short that they "lose" intensity. */ glShadeModel(GL_FLAT); } else { glDrawArrays( GL_POINTS, 0, nstars ); } /* Clear star movement. */ star_x = 0.; star_y = 0.; /* Disable vertex array. */ gl_vboDeactivate(); /* Pop matrix. */ gl_matrixPop(); /* Check for errors. */ gl_checkErr(); }