/* This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "stdafx.h" #include "openglskydome.h" #include "simulationenvironment.h" opengl_skydome::~opengl_skydome() { if( m_vertexbuffer != 0 ) { ::glDeleteBuffers( 1, &m_vertexbuffer ); } if( m_indexbuffer != 0 ) { ::glDeleteBuffers( 1, &m_indexbuffer ); } if( m_coloursbuffer != 0 ) { ::glDeleteBuffers( 1, &m_coloursbuffer ); } } void opengl_skydome::update() { auto &skydome { simulation::Environment.skydome() }; // cache entry state ::glPushClientAttrib( GL_CLIENT_VERTEX_ARRAY_BIT ); // setup gpu data buffers: // ...static data... if( m_indexbuffer == (GLuint)-1 ) { ::glGenBuffers( 1, &m_indexbuffer ); if( ( m_indexbuffer > 0 ) && ( m_indexbuffer != (GLuint)-1 ) ) { ::glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, m_indexbuffer ); auto const &indices { skydome.indices() }; ::glBufferData( GL_ELEMENT_ARRAY_BUFFER, indices.size() * sizeof( unsigned short ), indices.data(), GL_STATIC_DRAW ); m_indexcount = indices.size(); } } if( m_vertexbuffer == (GLuint)-1 ) { ::glGenBuffers( 1, &m_vertexbuffer ); if( ( m_vertexbuffer > 0 ) && ( m_vertexbuffer != (GLuint)-1 ) ) { ::glBindBuffer( GL_ARRAY_BUFFER, m_vertexbuffer ); auto const &vertices { skydome.vertices() }; ::glBufferData( GL_ARRAY_BUFFER, vertices.size() * sizeof( glm::vec3 ), vertices.data(), GL_STATIC_DRAW ); } } // ...and dynamic data if( m_coloursbuffer == (GLuint)-1 ) { ::glGenBuffers( 1, &m_coloursbuffer ); if( ( m_coloursbuffer > 0 ) && ( m_coloursbuffer != (GLuint)-1 ) ) { ::glBindBuffer( GL_ARRAY_BUFFER, m_coloursbuffer ); auto const &colors { skydome.colors() }; ::glBufferData( GL_ARRAY_BUFFER, colors.size() * sizeof( glm::vec3 ), colors.data(), GL_DYNAMIC_DRAW ); } } // ship the current dynamic data to the gpu // TODO: ship the data if it changed since the last update if( true == skydome.is_dirty() ) { if( ( m_coloursbuffer > 0 ) && ( m_coloursbuffer != (GLuint)-1 ) ) { ::glBindBuffer( GL_ARRAY_BUFFER, m_coloursbuffer ); auto &colors{ skydome.colors() }; /* float twilightfactor = clamp( -simulation::Environment.sun().getAngle(), 0.0f, 18.0f ) / 18.0f; auto gamma = interpolate( glm::vec3( 0.45f ), glm::vec3( 1.0f ), twilightfactor ); for( auto & color : colors ) { color = glm::pow( color, gamma ); } */ ::glBufferSubData( GL_ARRAY_BUFFER, 0, colors.size() * sizeof( glm::vec3 ), colors.data() ); skydome.is_dirty() = false; } } // cleanup ::glPopClientAttrib(); ::glBindBuffer( GL_ARRAY_BUFFER, 0 ); ::glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, 0 ); } // render skydome to screen void opengl_skydome::render() { if( ( m_indexbuffer == 0 ) || ( m_indexbuffer == (GLuint)-1 ) || ( m_vertexbuffer == 0 ) || ( m_vertexbuffer == (GLuint)-1 ) || ( m_coloursbuffer == 0 ) || ( m_coloursbuffer == (GLuint)-1 ) ) { return; } // setup: ::glPushClientAttrib( GL_CLIENT_VERTEX_ARRAY_BIT ); // ...positions... ::glBindBuffer( GL_ARRAY_BUFFER, m_vertexbuffer ); ::glVertexPointer( 3, GL_FLOAT, sizeof( glm::vec3 ), reinterpret_cast( 0 ) ); ::glEnableClientState( GL_VERTEX_ARRAY ); // ...colours... ::glBindBuffer( GL_ARRAY_BUFFER, m_coloursbuffer ); ::glColorPointer( 3, GL_FLOAT, sizeof( glm::vec3 ), reinterpret_cast( 0 ) ); ::glEnableClientState( GL_COLOR_ARRAY ); // ...indices ::glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, m_indexbuffer ); // draw ::glDrawElements( GL_TRIANGLES, static_cast( m_indexcount ), GL_UNSIGNED_SHORT, reinterpret_cast( 0 ) ); // cleanup ::glPopClientAttrib(); ::glBindBuffer( GL_ARRAY_BUFFER, 0 ); ::glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, 0 ); }