#include "gamemath/Matrix4x4f.h" #include "gamemath/Scalar.h" #include "renderer/Drawing.h" #include "renderer/GLIncludes.h" #include "renderer/Renderable.h" #include "renderer/Renderer.h" #include "shell/Shell.h" #include "shell/ShellCallbacks.h" #include "shell/ShellKeyCodes.h" #if defined(STEM_PLATFORM_macosx) #include "nsopenglshell/NSOpenGLShell.h" #include "nsopenglshell/NSOpenGLTarget.h" #elif defined(STEM_PLATFORM_iphonesimulator) || defined(STEM_PLATFORM_iphoneos) #include "eaglshell/EAGLShell.h" #include "eaglshell/EAGLTarget.h" #elif defined(STEM_PLATFORM_windows) #include "wglshell/WGLShell.h" #include "wglshell/WGLTarget.h" #elif defined(STEM_PLATFORM_linux) #include "glxshell/GLXShell.h" #include "glxshell/GLXTarget.h" #elif defined(STEM_PLATFORM_android) #include "eglshell/EGLShell.h" #include "eglshell/EGLTarget.h" #else #error Unsupported platform #endif #include #include #include #include #ifdef STEM_PLATFORM_android #include #define printf(format, ...) __android_log_print(ANDROID_LOG_INFO, "Renderer", format, ##__VA_ARGS__); #define fprintf(stderr, format, ...) __android_log_print(ANDROID_LOG_INFO, "Renderer", format, ##__VA_ARGS__); #endif #define PROJECTION_FOV 60.0f #define FBO_WIDTH 200 #define FBO_HEIGHT 150 static Renderer * renderer; static RenderLayer * renderLayer2D; static RenderLayer * renderLayer3D; //static Texture * checkerboardTexture; //static Texture * solidColorTexture; //static VertexBuffer * vertexBuffer; static ShaderUniformConfiguration perspectiveProjectionUniform; static ShaderUniformConfiguration orthoProjectionUniform; //static ShaderUniformConfiguration viewTransformUniform; static ShaderConfiguration * renderTargetShaderConfiguration; static unsigned int viewWidth = 1280, viewHeight = 720; static float viewRatio = 16.0f / 9.0f; static float scaleFactor = 1.0f; //static double animationStartTime, lastAnimationTime; static bool spriteMode; static RenderTarget * renderTarget; static bool useFBO; static Color4f clearColor; static bool Target_draw(double referenceTime, double activeDrawDelta) { if (useFBO) { Renderer_setRenderTarget(renderer, renderTarget); } Renderer_clear(renderer, clearColor); if (spriteMode) { Renderer_drawLayer(renderer, renderLayer2D, referenceTime, activeDrawDelta); } else { //ShaderUniformConfiguration_setMat4_Matrix4x4f(&viewTransformUniform, call_virtual(getTransform, camera)); Renderer_drawLayer(renderer, renderLayer3D, referenceTime, activeDrawDelta); } if (useFBO) { Renderer_setRenderTarget(renderer, NULL); Renderer_clear(renderer, clearColor); drawRenderTarget(renderer, renderTarget, renderTargetShaderConfiguration); } return true; } static void updateProjection() { float ratio; if (useFBO) { ratio = (float) FBO_WIDTH / FBO_HEIGHT; } else { ratio = viewRatio; } Matrix4x4f perspectiveMatrix = Matrix4x4f_perspective(MATRIX4x4f_IDENTITY, PROJECTION_FOV, ratio, 0.5f, 100.0f); ShaderUniformConfiguration_setMat4_Matrix4x4f(&perspectiveProjectionUniform, perspectiveMatrix); Matrix4x4f orthoMatrix = Matrix4x4f_ortho(MATRIX4x4f_IDENTITY, -ratio, ratio, -1.0f, 1.0f, -1.0f, 1.0f); ShaderUniformConfiguration_setMat4_Matrix4x4f(&orthoProjectionUniform, orthoMatrix); } static void Target_keyDown(unsigned int charCode, unsigned int keyCode, unsigned int modifiers, bool isRepeat, double referenceTime) { if (keyCode == KEY_CODE_E) { GLint extensionCount = 0; glGetIntegerv(GL_NUM_EXTENSIONS, &extensionCount); for (GLint extensionIndex = 0; extensionIndex < extensionCount; extensionIndex++) { const GLubyte * extensionString = glGetStringi(GL_EXTENSIONS, extensionIndex); printf("%s\n", extensionString); } } } static void Target_keyUp(unsigned int keyCode, unsigned int modifiers, double referenceTime) { } static void Target_keyModifiersChanged(unsigned int modifiers, unsigned int lastModifiers, double referenceTime) { } static void Target_mouseDown(unsigned int buttonNumber, unsigned int buttonMask, float x, float y, unsigned int modifierFlags, double referenceTime) { Shell_setMouseDeltaMode(true); } static void Target_mouseUp(unsigned int buttonNumber, unsigned int buttonMask, float x, float y, unsigned int modifierFlags, double referenceTime) { Shell_setMouseDeltaMode(false); } static void Target_mouseMoved(float x, float y, float deltaX, float deltaY, unsigned int modifierFlags, double referenceTime) { } #define SPRITE_DRAG_RATIO 0.003125f #define THRESHOLD_DRAG_RATIO 0.000625f #define SMOOTH_RANGE_DRAG_RATIO 0.0000625f static void Target_mouseDragged(unsigned int buttonMask, float x, float y, float deltaX, float deltaY, unsigned int modifierFlags, double referenceTime) { deltaX /= scaleFactor; deltaY /= scaleFactor; } static void Target_resized(unsigned int newWidth, unsigned int newHeight, double referenceTime) { viewWidth = newWidth; viewHeight = newHeight; viewRatio = (float) newWidth / newHeight; if (renderer != NULL) { Renderer_setViewport(renderer, 0, 0, viewWidth, viewHeight, NULL); updateProjection(); } } static void Target_backgrounded(double referenceTime) { } static void Target_foregrounded(double referenceTime) { } static void registerShellCallbacks() { Shell_drawFunc(Target_draw); Shell_resizeFunc(Target_resized); Shell_keyDownFunc(Target_keyDown); Shell_keyUpFunc(Target_keyUp); Shell_keyModifiersChangedFunc(Target_keyModifiersChanged); Shell_mouseDownFunc(Target_mouseDown); Shell_mouseUpFunc(Target_mouseUp); Shell_mouseMovedFunc(Target_mouseMoved); Shell_mouseDraggedFunc(Target_mouseDragged); Shell_backgroundedFunc(Target_backgrounded); Shell_foregroundedFunc(Target_foregrounded); } #if defined(STEM_PLATFORM_macosx) void NSOpenGLTarget_configure(int argc, const char ** argv, struct NSOpenGLShellConfiguration * configuration) { configuration->windowTitle = "Renderer"; configuration->useGLCoreProfile = true; configuration->displayMode.depthBuffer = true; #elif defined(STEM_PLATFORM_iphonesimulator) || defined(STEM_PLATFORM_iphoneos) void EAGLTarget_configure(int argc, char ** argv, struct EAGLShellConfiguration * configuration) { configuration->displayMode.depthAttachment = true; configuration->displayMode.depthPrecision = 24; #elif defined(STEM_PLATFORM_windows) void WGLTarget_configure(void * instance, void * prevInstance, char * commandLine, int command, int argc, const char ** argv, struct WGLShellConfiguration * configuration) { configuration->windowTitle = "Renderer"; configuration->useGLCoreProfile = true; configuration->displayMode.depthBuffer = true; #elif defined(STEM_PLATFORM_linux) void GLXTarget_configure(int argc, const char ** argv, struct GLXShellConfiguration * configuration) { #include "IconData_stemapp.h" configuration->icon.data = STATIC_iconData_stemapp; configuration->icon.size = sizeof(STATIC_iconData_stemapp) / sizeof(STATIC_iconData_stemapp[0]); configuration->applicationName = STEM_HUMAN_READABLE_TARGET_NAME; configuration->windowTitle = "Renderer"; configuration->displayMode.depthBuffer = true; #elif defined(STEM_PLATFORM_android) void EGLTarget_configure(struct EGLShellConfiguration * configuration) { configuration->displayMode.depthSize = 24; #else void GLUTTarget_configure(int argc, const char ** argv, struct GLUTShellConfiguration * configuration) { configuration->windowTitle = "Renderer"; configuration->displayMode.depthBuffer = true; #endif scaleFactor = Shell_getDisplayScaleFactor(Shell_getDisplayIndexFromWindow()); registerShellCallbacks(); } void Target_init() { renderer = Renderer_create(); renderLayer2D = RenderLayer_create(RENDER_LAYER_SORT_NONE, NULL, NULL); renderLayer3D = RenderLayer_create(RENDER_LAYER_SORT_NONE, NULL, NULL); renderTarget = RenderTarget_create(FBO_WIDTH, FBO_HEIGHT, true, false); // Test harness tasks: // - Basic renderer usage: Clear, clear depth, draw layer, draw single // - RenderLayer: Callback, list management, options // - Multiple shaders, vertex format // - VertexBuffer buffer/map data // - Texture: All types, swizzle, update options // - RenderTarget: Draw, readback // - RenderDataBuffer: Shader data transfer // - Renderable: All types // Remove SpriteRenderable? Rehome Animation/AnimationState/Armature? Camera/OrbitCamera/WalkCamera? TextureAtlas? Shell_mainLoop(); }