/** * \brief Draws the vertices in the case where there are textures. */ void bear::visual::gl_state::draw_textured() const { if ( m_vertices.empty() ) return; enable_shader(); set_colors(); set_vertices(); set_texture_coordinates(); for ( element_range_list::const_iterator it(m_elements.begin()); it!=m_elements.end(); ++it ) { glBindTexture( GL_TEXTURE_2D, it->texture_id ); VISUAL_GL_ERROR_THROW(); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); VISUAL_GL_ERROR_THROW(); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); VISUAL_GL_ERROR_THROW(); glDrawArrays( get_gl_render_mode(), it->vertex_index, it->count ); VISUAL_GL_ERROR_THROW(); } disable_states(); } // gl_state::draw_textured()
/** * \brief Passes the color pointer to OpenGL. */ void bear::visual::gl_state::set_colors() const { glEnableClientState( GL_COLOR_ARRAY ); VISUAL_GL_ERROR_THROW(); glColorPointer( 4, GL_FLOAT, 0, m_colors.data() ); VISUAL_GL_ERROR_THROW(); } // gl_state::set_colors()
/** * \brief Passes the vertex pointer to OpenGL. */ void bear::visual::gl_state::set_vertices() const { glEnableClientState( GL_VERTEX_ARRAY ); VISUAL_GL_ERROR_THROW(); glVertexPointer( 2, GL_FLOAT, 0, m_vertices.data() ); VISUAL_GL_ERROR_THROW(); } // gl_state::set_vertices()
/** * \brief Passes the pointer on the texture coordinates to OpenGL. */ void bear::visual::gl_state::set_texture_coordinates() const { glEnableClientState( GL_TEXTURE_COORD_ARRAY ); VISUAL_GL_ERROR_THROW(); glTexCoordPointer( 2, GL_FLOAT, 0, m_texture_coordinates.data() ); VISUAL_GL_ERROR_THROW(); } // gl_state::set_texture_coordinates()
/** * \brief Draw a filled polygon. * \param color The color of the polygon. * \param p The points of the polygon. */ void bear::visual::gl_screen::draw_polygon ( const color_type& color, const std::vector<position_type>& p ) { glBindTexture( GL_TEXTURE_2D, 0 ); VISUAL_GL_ERROR_THROW(); const GLfloat max = std::numeric_limits<color_type::component_type>::max(); if (color.components.alpha != max) { glEnable(GL_BLEND); VISUAL_GL_ERROR_THROW(); } glBegin(GL_QUADS); { glColor4f( (GLfloat)color.components.red / max, (GLfloat)color.components.green / max, (GLfloat)color.components.blue / max, (GLfloat)color.components.alpha / max ); for ( unsigned int i=0; i!=p.size(); ++i ) glVertex3f( p[i].x, p[i].y, m_z_position ); } glEnd(); VISUAL_GL_ERROR_THROW(); update_z_position(); if (color.components.alpha != max) { glDisable(GL_BLEND); VISUAL_GL_ERROR_THROW(); } } // gl_screen::draw_polygon()
/** * \brief Tells OpenGL to disable the texture coordinates, the vertices and the * colors. */ void bear::visual::gl_state::disable_states() const { glDisableClientState( GL_TEXTURE_COORD_ARRAY ); VISUAL_GL_ERROR_THROW(); glDisableClientState( GL_VERTEX_ARRAY ); VISUAL_GL_ERROR_THROW(); glDisableClientState( GL_COLOR_ARRAY ); VISUAL_GL_ERROR_THROW(); } // gl_state::draw_textured()
/** * \brief Draw current texture. * \param render_box On gl_screen position and size of the texture. * \param clip Part of the texture to draw. */ void bear::visual::gl_screen::render_image ( const claw::math::coordinate_2d<GLdouble> render_coord[], const claw::math::box_2d<GLdouble>& clip ) { glBegin(GL_QUADS); { // Top-left corner glTexCoord2d( clip.first_point.x, clip.first_point.y ); glVertex3d(render_coord[0].x, render_coord[0].y, m_z_position); // Top-right corner glTexCoord2d( clip.second_point.x, clip.first_point.y ); glVertex3d(render_coord[1].x, render_coord[1].y, m_z_position); // Bottom-right corner glTexCoord2d( clip.second_point.x, clip.second_point.y ); glVertex3d(render_coord[2].x, render_coord[2].y, m_z_position); // Bottom-left corner glTexCoord2d( clip.first_point.x, clip.second_point.y ); glVertex3d(render_coord[3].x, render_coord[3].y, m_z_position); } glEnd(); VISUAL_GL_ERROR_THROW(); update_z_position(); } // gl_screen::render_image()
/** * \brief Sets the value of a boolean uniform. * \param name The name of the uniform. * \param value The value to assign to the uniform. */ void bear::visual::gl_state::uniform_setter::operator() ( std::string name, bool value ) const { glUniform1i( glGetUniformLocation( m_program, name.c_str() ), value); VISUAL_GL_ERROR_THROW(); } // gl_state::uniform_setter::operator()()
void bear::visual::detail::uniform_setter::operator() ( const std::string& name, const std::array< float, 16 >& value ) const { glUniformMatrix4fv ( glGetUniformLocation( m_program, name.c_str() ), 1, GL_FALSE, value.data() ); VISUAL_GL_ERROR_THROW(); }
/** * \brief Stop the rendering process. * \return false if this screen has been closed by the user. */ bool bear::visual::gl_screen::end_render() { glFlush(); SDL_GL_SwapBuffers(); VISUAL_GL_ERROR_THROW(); return !is_closed(); } // gl_screen::end_render()
/** * \brief Sets a new dimension for the resulting projection to match the size of * the screen. */ void bear::visual::gl_screen::resize_view() { glViewport( 0, 0, m_window_size.x, m_window_size.y ); glMatrixMode(GL_PROJECTION); glLoadIdentity(); glOrtho( 0, m_size.x, 0, m_size.y, -1, 0 ); glMatrixMode(GL_MODELVIEW); VISUAL_GL_ERROR_THROW(); } // gl_screen::resize_view()
/** * \brief Enables the shader of the state. */ void bear::visual::gl_state::enable_shader() const { if ( !m_shader.is_valid() ) { glUseProgram( 0 ); VISUAL_GL_ERROR_THROW(); return; } const gl_shader_program* const s ( static_cast<const gl_shader_program*>( m_shader.get_impl() ) ); glUseProgram( s->program_id() ); VISUAL_GL_ERROR_THROW(); shader_program::variable_visitor_type visitor; shader_program::input_variable_map vars( m_shader.get_variables() ); visitor.run( vars, uniform_setter( s->program_id() ) ); } // gl_state::enable_shader()
/** * \brief Initialize the rendering process. */ void bear::visual::gl_screen::begin_render() { VISUAL_GL_ERROR_THROW(); while ( !m_shader.empty() ) pop_shader(); glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ); m_z_position = 0; resize_view(); } // gl_screen::begin_render()
/** * \brief Enables a given shader. * \param p The shader to enable. */ void bear::visual::gl_screen::use_program( const shader_program& p ) const { const gl_shader_program* const s ( static_cast<const gl_shader_program*>(p.get_impl()) ); glUseProgram( s->program_id() ); VISUAL_GL_ERROR_THROW(); shader_program::variable_visitor_type visitor; shader_program::input_variable_map vars( p.get_variables() ); visitor.run( vars, uniform_setter( s->program_id() ) ); } // gl_screen::use_program()
/** * \brief Draws the vertices in the case where there is no texture. */ void bear::visual::gl_state::draw_shape() const { if ( m_vertices.empty() ) return; enable_shader(); if ( m_line_width > 0 ) { glLineWidth( m_line_width ); VISUAL_GL_ERROR_THROW(); } set_colors(); set_vertices(); glBindTexture( GL_TEXTURE_2D, 0 ); VISUAL_GL_ERROR_THROW(); glDrawArrays( get_gl_render_mode(), 0, get_vertex_count() ); disable_states(); } // gl_state::draw_shape()
void bear::visual::detail::apply_shader( const shader_program& shader ) { assert ( shader.is_valid() ); const gl_shader_program* const s ( static_cast<const gl_shader_program*>( shader.get_impl() ) ); assert( s->program_id() != 0 ); glUseProgram( s->program_id() ); VISUAL_GL_ERROR_THROW(); shader_program::variable_visitor_type visitor; shader_program::input_variable_map vars( shader.get_variables() ); visitor.run( vars, uniform_setter( s->program_id() ) ); }
/** * \brief Do a screen shot. * \param img The image in which we save the content of the gl_screen. */ void bear::visual::gl_screen::shot( claw::graphic::image& img ) const { GLint p[4]; glGetIntegerv( GL_VIEWPORT, p ); const unsigned int w = p[2]; const unsigned int h = p[3]; img.set_size( w, h ); const std::size_t pixels_count(w * h); glReadPixels( 0, 0, w, h, GL_RGBA, GL_UNSIGNED_BYTE, m_screenshot_buffer ); VISUAL_GL_ERROR_THROW(); for ( claw::graphic::rgba_pixel_8* it=m_screenshot_buffer; it!=m_screenshot_buffer + pixels_count; ++it ) it->components.alpha = 255; for (unsigned int y=0; y!=h; ++y) std::copy( m_screenshot_buffer + y * w, m_screenshot_buffer + (y+1) * w, img[h - y - 1].begin() ); } // gl_screen::shot()
/** * \brief Draw a sprite on the gl_screen. * \param pos On gl_screen position of the sprite. * \param s The sprite to draw. */ void bear::visual::gl_screen::render ( const position_type& pos, const sprite& s ) { if ( s.has_transparency() ) { glEnable(GL_BLEND); VISUAL_GL_ERROR_THROW(); } glColor4f( s.get_red_intensity(), s.get_green_intensity(), s.get_blue_intensity(), s.get_opacity() ); const gl_image* impl = static_cast<const gl_image*>(s.get_image().get_impl()); glBindTexture( GL_TEXTURE_2D, impl->texture_id() ); VISUAL_GL_ERROR_THROW(); if ( s.get_angle() == 0 ) { glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); VISUAL_GL_ERROR_THROW(); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); VISUAL_GL_ERROR_THROW(); } else { glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); VISUAL_GL_ERROR_THROW(); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); VISUAL_GL_ERROR_THROW(); } render_sprite( pos, s ); if ( s.has_transparency() ) { glDisable(GL_BLEND); VISUAL_GL_ERROR_THROW(); } } // gl_screen::render()
/** * \brief Set the size of the screen. * \param w The width of the screen. * \param h The height of the screen. * \param f Tell if we want a fullscreen mode. */ void bear::visual::gl_screen::set_video_mode ( unsigned int w, unsigned int h, bool f ) { const screen_size_type best_size( get_best_screen_size(w, h, f) ); SDL_Surface* const current_surface = SDL_GetVideoSurface(); if ( current_surface != NULL ) { if ( ( ( (current_surface->flags & SDL_FULLSCREEN) != 0) == f ) && (w == (unsigned int)current_surface->w) && (h != (unsigned int)current_surface->h) ) return; } #ifdef _WIN32 release(); initialize(); #endif Uint32 flags = SDL_OPENGL; if (f) flags |= SDL_FULLSCREEN; claw::logger << "Setting video mode to " << best_size.x << 'x' << best_size.y << ' ' << (f ? "fullscreen" : "windowed") << std::endl; SDL_EventState( SDL_QUIT, SDL_DISABLE ); SDL_Surface* s = SDL_SetVideoMode( best_size.x, best_size.y, 32, flags ); SDL_EventState( SDL_QUIT, SDL_ENABLE ); if (!s) throw claw::exception( SDL_GetError() ); m_window_size = best_size; delete[] m_screenshot_buffer; m_screenshot_buffer = new claw::graphic::rgba_pixel_8[ best_size.x * best_size.y ]; SDL_ShowCursor(0); glClearColor(0.0, 0.0, 0.0, 0.0); glClearDepth(1.0); #ifdef _WIN32 glEnable(GL_TEXTURE_2D); VISUAL_GL_ERROR_THROW(); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); VISUAL_GL_ERROR_THROW(); SDL_WM_SetCaption( m_title.c_str(), NULL ); claw::logger << claw::log_verbose << "Screen needs restoration (was " << m_need_restoration << ")." << std::endl; m_need_restoration = true; #endif } // gl_screen::set_video_mode()
void bear::visual::detail::uniform_setter::operator() ( const std::string& name, float value ) const { glUniform1f( glGetUniformLocation( m_program, name.c_str() ), value); VISUAL_GL_ERROR_THROW(); }