mirror of
https://github.com/SpartanJ/eepp.git
synced 2026-10-01 10:40:20 +03:00
complete scoped ownership migration
- migrate themes, skins, icons, shaders, and shader programs to resource handles - make UIThemeManager scene-owned and publish resources through scopes and catalogs - retain shaders through their programs and expose non-owning GPU registries - replace FrameBuffer and VertexBuffer factory ownership with unique pointers - migrate engine, UI, tools, examples, tests, and eterm to the new ownership APIs - remove the obsolete raw-owning ResourceManager templates - document the completed Stage 7 architecture and remaining validation work - add ownership, registry, and scoped shader-program coverage
This commit is contained in:
@@ -8,31 +8,35 @@ namespace Demo_ExternalShader {
|
||||
static Float sqrt_approx[20001];
|
||||
#endif
|
||||
|
||||
Uint32 ParticlesNum = 30000;
|
||||
static constexpr Uint32 ParticlesNum = 30000;
|
||||
|
||||
EE::Window::Window* win = NULL;
|
||||
Input* imp = NULL;
|
||||
ShaderProgram* shaderProgram = NULL;
|
||||
bool ShadersSupported = false;
|
||||
Float tw;
|
||||
Float th;
|
||||
Float aspectRatio;
|
||||
Vector3ff* vertices = eeNewArray( Vector3ff, ParticlesNum );
|
||||
Vector3ff* velocities = eeNewArray( Vector3ff, ParticlesNum );
|
||||
ColorAf* colors = eeNewArray( ColorAf, ParticlesNum );
|
||||
struct ExampleState {
|
||||
EE::Window::Window* win{ nullptr };
|
||||
Input* input{ nullptr };
|
||||
ShaderProgramPtr shaderProgram;
|
||||
bool shadersSupported{ false };
|
||||
Float halfWidth{ 0 };
|
||||
Float halfHeight{ 0 };
|
||||
Float aspectRatio{ 0 };
|
||||
std::vector<Vector3ff> vertices{ ParticlesNum };
|
||||
std::vector<Vector3ff> velocities{ ParticlesNum };
|
||||
std::vector<ColorAf> colors{ ParticlesNum };
|
||||
};
|
||||
|
||||
void videoResize( EE::Window::Window* ) {
|
||||
void videoResize( ExampleState& state, EE::Window::Window* ) {
|
||||
auto* win = state.win;
|
||||
auto& shaderProgram = state.shaderProgram;
|
||||
/// Video Resize event will re-setup the 2D projection and states, so we must rebuild them.
|
||||
aspectRatio = (Float)win->getWidth() / (Float)win->getHeight();
|
||||
tw = (Float)win->getWidth() / 2;
|
||||
th = (Float)win->getHeight() / 2;
|
||||
state.aspectRatio = (Float)win->getWidth() / (Float)win->getHeight();
|
||||
state.halfWidth = (Float)win->getWidth() / 2;
|
||||
state.halfHeight = (Float)win->getHeight() / 2;
|
||||
|
||||
float fieldOfView = 30.0;
|
||||
float nearPlane = 1.0;
|
||||
float farPlane = 10000.0;
|
||||
float top = nearPlane * eetan( fieldOfView * EE_PI_360 );
|
||||
float bottom = -top;
|
||||
float right = top * aspectRatio;
|
||||
float right = top * state.aspectRatio;
|
||||
float left = -right;
|
||||
|
||||
float a = ( right + left ) / ( right - left );
|
||||
@@ -63,7 +67,7 @@ void videoResize( EE::Window::Window* ) {
|
||||
/// Set the line width
|
||||
GLi->lineWidth( 2 );
|
||||
|
||||
if ( ShadersSupported ) {
|
||||
if ( state.shadersSupported ) {
|
||||
/// Rebind the Shader
|
||||
shaderProgram->bind();
|
||||
|
||||
@@ -87,7 +91,13 @@ void videoResize( EE::Window::Window* ) {
|
||||
} // namespace Demo_ExternalShader
|
||||
using namespace Demo_ExternalShader;
|
||||
|
||||
void mainLoop() {
|
||||
void mainLoop( ExampleState& state ) {
|
||||
auto* win = state.win;
|
||||
auto* imp = state.input;
|
||||
auto& vertices = state.vertices;
|
||||
auto& velocities = state.velocities;
|
||||
auto& colors = state.colors;
|
||||
const Float aspectRatio = state.aspectRatio;
|
||||
win->clear();
|
||||
|
||||
imp->update();
|
||||
@@ -108,9 +118,9 @@ void mainLoop() {
|
||||
|
||||
Float p;
|
||||
Vector2f mf = imp->getMousePos().asFloat();
|
||||
Float tratio = tw / th;
|
||||
Float touchX = ( mf.x / tw - 1 ) * tratio;
|
||||
Float touchY = -( mf.y / th - 1 );
|
||||
Float tratio = state.halfWidth / state.halfHeight;
|
||||
Float touchX = ( mf.x / state.halfWidth - 1 ) * tratio;
|
||||
Float touchY = -( mf.y / state.halfHeight - 1 );
|
||||
bool touch = imp->isMouseLeftPressed();
|
||||
|
||||
for ( Uint32 i = 0; i < ParticlesNum; i += 2 ) {
|
||||
@@ -197,7 +207,13 @@ void mainLoop() {
|
||||
win->display();
|
||||
}
|
||||
|
||||
EE_MAIN_FUNC int main( int argc, char* argv[] ) {
|
||||
static int run() {
|
||||
ExampleState state;
|
||||
auto& win = state.win;
|
||||
auto& shaderProgram = state.shaderProgram;
|
||||
auto& vertices = state.vertices;
|
||||
auto& velocities = state.velocities;
|
||||
auto& colors = state.colors;
|
||||
win = Engine::instance()->createWindow( WindowSettings( 960, 640, "eepp - External Shaders" ),
|
||||
ContextSettings( true ) );
|
||||
|
||||
@@ -205,13 +221,13 @@ EE_MAIN_FUNC int main( int argc, char* argv[] ) {
|
||||
return EXIT_FAILURE;
|
||||
|
||||
/// This will work without shaders too
|
||||
ShadersSupported = GLi->shadersSupported();
|
||||
state.shadersSupported = GLi->shadersSupported();
|
||||
|
||||
imp = win->getInput();
|
||||
state.input = win->getInput();
|
||||
|
||||
/// We really don't need shaders for this, but the purpose of the example is to show how to
|
||||
/// work with external shaders
|
||||
if ( ShadersSupported ) {
|
||||
if ( state.shadersSupported ) {
|
||||
/// Disable the automatic shader conversion from fixed-pipeline to programmable-pipeline
|
||||
Shader::ensure( false );
|
||||
|
||||
@@ -246,10 +262,11 @@ EE_MAIN_FUNC int main( int argc, char* argv[] ) {
|
||||
}
|
||||
|
||||
/// Set the projection
|
||||
videoResize( win );
|
||||
videoResize( state, win );
|
||||
|
||||
/// Push a window resize callback the reset the projection when needed
|
||||
win->pushResizeCallback( videoResize );
|
||||
win->pushResizeCallback(
|
||||
[&state]( EE::Window::Window* window ) { videoResize( state, window ); } );
|
||||
|
||||
Uint32 i;
|
||||
|
||||
@@ -269,15 +286,17 @@ EE_MAIN_FUNC int main( int argc, char* argv[] ) {
|
||||
}
|
||||
#endif
|
||||
|
||||
win->runMainLoop( &mainLoop );
|
||||
win->runMainLoop( [&state] { mainLoop( state ); } );
|
||||
|
||||
eeSAFE_DELETE_ARRAY( vertices );
|
||||
eeSAFE_DELETE_ARRAY( velocities );
|
||||
eeSAFE_DELETE_ARRAY( colors );
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
EE_MAIN_FUNC int main( int, char*[] ) {
|
||||
int result = run();
|
||||
|
||||
Engine::destroySingleton();
|
||||
|
||||
MemoryManager::showResults();
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -1,118 +1,8 @@
|
||||
#include <eepp/ee.hpp>
|
||||
|
||||
EE::Window::Window* win = NULL;
|
||||
VertexBuffer* VBO = NULL;
|
||||
VertexBuffer* VBO2 = NULL;
|
||||
FrameBuffer* FBO = NULL;
|
||||
|
||||
// The batch renderer class is designed to take control of almost all the rendering needed by the
|
||||
// engine. Controls that the rendering is only done when is needed, preventing redundant OpenGL API
|
||||
// calls Usually the user will not need to use this class manually, since eepp controls this
|
||||
// internally. The engine uses the singleton class GlobalBatchRenderer instance to render textures
|
||||
// and primitives.
|
||||
BatchRenderer* Batch = BatchRenderer::New();
|
||||
|
||||
Float ang = 0, scale = 1;
|
||||
bool side = false;
|
||||
|
||||
void mainLoop() {
|
||||
// Clear the screen buffer
|
||||
win->clear();
|
||||
|
||||
// Update the input
|
||||
win->getInput()->update();
|
||||
|
||||
// Check if ESCAPE key is pressed
|
||||
if ( win->getInput()->isKeyDown( KEY_ESCAPE ) ) {
|
||||
// Close the window
|
||||
win->close();
|
||||
}
|
||||
|
||||
// Bind the Frame Buffer, everything rendered from here will be rendered in the frame buffer
|
||||
FBO->bind();
|
||||
{
|
||||
// Bind the buffered data ( activate the buffer )
|
||||
VBO->bind();
|
||||
|
||||
// Draw the buffered data
|
||||
VBO->draw();
|
||||
|
||||
// Unbind the buffered data
|
||||
VBO->unbind();
|
||||
|
||||
// Same as above
|
||||
VBO2->bind();
|
||||
VBO2->draw();
|
||||
VBO2->unbind();
|
||||
}
|
||||
// Unbind the frame buffer. Stops rendering to the frame buffer
|
||||
FBO->unbind();
|
||||
|
||||
// Draw the frame buffer many times
|
||||
for ( int y = 0; y < 5; y++ ) {
|
||||
for ( int x = 0; x < 5; x++ ) {
|
||||
FBO->getTexture()->draw( x * 200, y * 200, -ang, Vector2f::One,
|
||||
Color( 255, 255, 255, 100 ) );
|
||||
}
|
||||
}
|
||||
|
||||
Float HWidth = win->getWidth() * 0.5f;
|
||||
Float HHeight = win->getHeight() * 0.5f;
|
||||
|
||||
// The batch can be rotated, scale and moved
|
||||
Batch->setBatchRotation( ang );
|
||||
Batch->setBatchScale( scale );
|
||||
Batch->setBatchCenter( Vector2f( HWidth, HHeight ) );
|
||||
|
||||
// Create a quad to render
|
||||
Float aX = HWidth - 256.f;
|
||||
Float aY = HHeight - 256.f;
|
||||
Quad2f TmpQuad( Vector2f( aX, aY ), Vector2f( aX, aY + 32.f ), Vector2f( aX + 32.f, aY + 32.f ),
|
||||
Vector2f( aX + 32.f, aY ) );
|
||||
TmpQuad.rotate( ang, Vector2f( aX + 16.f, aY + 16.f ) );
|
||||
|
||||
// Begin drawing quads
|
||||
Batch->quadsBegin();
|
||||
|
||||
// Add some quads to the batch renderer
|
||||
for ( Uint32 z = 0; z < 16; z++ ) {
|
||||
for ( Uint32 y = 0; y < 16; y++ ) {
|
||||
Float tmpx = (Float)z * 32.f;
|
||||
Float tmpy = (Float)y * 32.f;
|
||||
|
||||
// Add the quad to the batch
|
||||
Batch->quadsSetColor( Color( z * 16, 255, 255, 150 ) );
|
||||
Batch->batchQuadFree( TmpQuad[0].x + tmpx, TmpQuad[0].y + tmpy, TmpQuad[1].x + tmpx,
|
||||
TmpQuad[1].y + tmpy, TmpQuad[2].x + tmpx, TmpQuad[2].y + tmpy,
|
||||
TmpQuad[3].x + tmpx, TmpQuad[3].y + tmpy );
|
||||
}
|
||||
}
|
||||
|
||||
// Draw the batched quads
|
||||
Batch->draw();
|
||||
|
||||
// Add the rotation angle
|
||||
ang += win->getElapsed().asMilliseconds() * 0.1f;
|
||||
ang = ( ang >= 360 ) ? 0 : ang;
|
||||
|
||||
// Change the scale value
|
||||
if ( scale >= 1.5f ) {
|
||||
scale = 1.5f;
|
||||
side = true;
|
||||
} else if ( scale <= 0.5f ) {
|
||||
side = false;
|
||||
scale = 0.5f;
|
||||
}
|
||||
scale = ( !side ) ? scale + win->getElapsed().asMilliseconds() * 0.00025f
|
||||
: scale - win->getElapsed().asMilliseconds() * 0.00025f;
|
||||
|
||||
// Draw frame
|
||||
win->display();
|
||||
}
|
||||
|
||||
EE_MAIN_FUNC int main( int, char*[] ) {
|
||||
// Create a new window
|
||||
win = Engine::instance()->createWindow(
|
||||
auto* win = Engine::instance()->createWindow(
|
||||
WindowSettings( 1024, 768, "eepp - VBO - FBO and Batch Rendering" ),
|
||||
ContextSettings( true ) );
|
||||
|
||||
@@ -121,14 +11,18 @@ EE_MAIN_FUNC int main( int, char*[] ) {
|
||||
|
||||
// Check if created
|
||||
if ( win->isOpen() ) {
|
||||
auto VBO = VertexBuffer::New( VERTEX_FLAGS_PRIMITIVE, PRIMITIVE_TRIANGLE_FAN );
|
||||
auto VBO2 = VertexBuffer::New( VERTEX_FLAGS_PRIMITIVE, PRIMITIVE_TRIANGLE_FAN );
|
||||
auto FBO = FrameBuffer::New( 200, 200 );
|
||||
auto* Batch = BatchRenderer::New();
|
||||
Float ang = 0;
|
||||
Float scale = 1;
|
||||
bool side = false;
|
||||
Polygon2f Poly( Polygon2f::createRoundedRectangle( 0, 0, 200, 50 ) );
|
||||
|
||||
// Create the Vertex Buffer, the vertex buffer stores the vertex data in the GPU, making the
|
||||
// rendering much faster In the case that Vertex Buffer Object is not supported by the GPU,
|
||||
// it will fallback to a immediate-mode vertex buffer
|
||||
VBO = VertexBuffer::New( VERTEX_FLAGS_PRIMITIVE, PRIMITIVE_TRIANGLE_FAN );
|
||||
VBO2 = VertexBuffer::New( VERTEX_FLAGS_PRIMITIVE, PRIMITIVE_TRIANGLE_FAN );
|
||||
|
||||
// Add the vertex and vertex colors to the Vertex Buffer
|
||||
if ( NULL != VBO && NULL != VBO2 ) {
|
||||
for ( Uint32 i = 0; i < Poly.getSize(); i++ ) {
|
||||
@@ -148,17 +42,66 @@ EE_MAIN_FUNC int main( int, char*[] ) {
|
||||
VBO2->compile();
|
||||
}
|
||||
|
||||
// Create a new frame buffer. It will use Framebuffer Objects if available, otherwise it
|
||||
// will try to fallback to PBuffers.
|
||||
FBO = FrameBuffer::New( 200, 200 );
|
||||
|
||||
// Application loop
|
||||
win->runMainLoop( &mainLoop );
|
||||
win->runMainLoop( [&] {
|
||||
win->clear();
|
||||
win->getInput()->update();
|
||||
if ( win->getInput()->isKeyDown( KEY_ESCAPE ) )
|
||||
win->close();
|
||||
|
||||
FBO->bind();
|
||||
VBO->bind();
|
||||
VBO->draw();
|
||||
VBO->unbind();
|
||||
VBO2->bind();
|
||||
VBO2->draw();
|
||||
VBO2->unbind();
|
||||
FBO->unbind();
|
||||
|
||||
for ( int y = 0; y < 5; y++ )
|
||||
for ( int x = 0; x < 5; x++ )
|
||||
FBO->getTexture()->draw( x * 200, y * 200, -ang, Vector2f::One,
|
||||
Color( 255, 255, 255, 100 ) );
|
||||
|
||||
Float halfWidth = win->getWidth() * 0.5f;
|
||||
Float halfHeight = win->getHeight() * 0.5f;
|
||||
Batch->setBatchRotation( ang );
|
||||
Batch->setBatchScale( scale );
|
||||
Batch->setBatchCenter( Vector2f( halfWidth, halfHeight ) );
|
||||
|
||||
Float x = halfWidth - 256.f;
|
||||
Float y = halfHeight - 256.f;
|
||||
Quad2f quad( Vector2f( x, y ), Vector2f( x, y + 32.f ), Vector2f( x + 32.f, y + 32.f ),
|
||||
Vector2f( x + 32.f, y ) );
|
||||
quad.rotate( ang, Vector2f( x + 16.f, y + 16.f ) );
|
||||
|
||||
Batch->quadsBegin();
|
||||
for ( Uint32 column = 0; column < 16; column++ ) {
|
||||
for ( Uint32 row = 0; row < 16; row++ ) {
|
||||
Float offsetX = static_cast<Float>( column ) * 32.f;
|
||||
Float offsetY = static_cast<Float>( row ) * 32.f;
|
||||
Batch->quadsSetColor( Color( column * 16, 255, 255, 150 ) );
|
||||
Batch->batchQuadFree( quad[0].x + offsetX, quad[0].y + offsetY,
|
||||
quad[1].x + offsetX, quad[1].y + offsetY,
|
||||
quad[2].x + offsetX, quad[2].y + offsetY,
|
||||
quad[3].x + offsetX, quad[3].y + offsetY );
|
||||
}
|
||||
}
|
||||
Batch->draw();
|
||||
|
||||
ang += win->getElapsed().asMilliseconds() * 0.1f;
|
||||
ang = ang >= 360 ? 0 : ang;
|
||||
if ( scale >= 1.5f ) {
|
||||
scale = 1.5f;
|
||||
side = true;
|
||||
} else if ( scale <= 0.5f ) {
|
||||
scale = 0.5f;
|
||||
side = false;
|
||||
}
|
||||
scale += ( side ? -1.f : 1.f ) * win->getElapsed().asMilliseconds() * 0.00025f;
|
||||
win->display();
|
||||
} );
|
||||
|
||||
// Release the allocated objects ( VBOs and FBOs need to be released manually )
|
||||
eeSAFE_DELETE( VBO );
|
||||
eeSAFE_DELETE( VBO2 );
|
||||
eeSAFE_DELETE( FBO );
|
||||
eeSAFE_DELETE( Batch );
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user