diff --git a/BeefySysLib/platform/sdl/GLRenderDevice.cpp b/BeefySysLib/platform/sdl/GLRenderDevice.cpp index 160031630..e71420339 100644 --- a/BeefySysLib/platform/sdl/GLRenderDevice.cpp +++ b/BeefySysLib/platform/sdl/GLRenderDevice.cpp @@ -40,13 +40,16 @@ USING_NS_BF; #endif extern void* (SDLCALL* bf_SDL_GL_GetProcAddress)(const char* proc); -extern bool (SDLCALL* bf_SDL_GetWindowSize)(SDL_Window* window, int* w, int* h); +extern bool (SDLCALL* bf_SDL_GetWindowSizeInPixels)(SDL_Window* window, int* w, int* h); extern bool (SDLCALL* bf_SDL_GL_SwapWindow)(SDL_Window* window); extern bool (SDLCALL* bf_SDL_GL_MakeCurrent)(SDL_Window* window, SDL_GLContext context); +extern SDL_GLContext (SDLCALL* bf_SDL_GL_GetCurrentContext)(); +extern const char* (SDLCALL* bf_SDL_GetError)(void); -typedef void (APIENTRYP GL_DEBUGPROC)(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar* message, const void* userParam); +extern SDL_DisplayID (SDLCALL* bf_SDL_GetDisplayForWindow)(SDL_Window *window); +extern const SDL_DisplayMode* (SDLCALL* bf_SDL_GetCurrentDisplayMode)(SDL_DisplayID displayID); -static void (APIENTRYP bf_glDebugMessageCallback)(GL_DEBUGPROC callback, const void* userParam); +static GLenum (APIENTRYP bf_glGetError)(); static void (APIENTRYP bf_glActiveTexture)(GLenum texture); static void (APIENTRYP bf_glGenVertexArrays)(GLsizei n, GLuint* buffers); static void (APIENTRYP bf_glBindVertexArray)(GLenum target); @@ -109,10 +112,104 @@ static void (APIENTRYP bf_glGetObjectParameterivARB)(GLint obj, GLenum pname, GL static void (APIENTRYP bf_glCompressedTexImage2D)(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid *data); static void (APIENTRYP bf_glClientActiveTexture)(GLenum texture); +static void (APIENTRYP bf_glGenTextures)(GLsizei n, GLuint *textures); +static void (APIENTRYP bf_glBindTexture)(GLenum target, GLuint texture); +static void (APIENTRYP bf_glPixelStorei)(GLenum pname, GLint param); +static void (APIENTRYP bf_glTexImage2D)(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const void *pixels); +static void (APIENTRYP bf_glTexParameteri)(GLenum target, GLenum pname, GLint param); +static void (APIENTRYP bf_glDisable)(GLenum cap); +static void (APIENTRYP bf_glEnable)(GLenum cap); +static void (APIENTRYP bf_glCullFace)(GLenum mode); +static void (APIENTRYP bf_glDepthFunc)(GLenum mode); +static void (APIENTRYP bf_glDepthMask)(GLboolean flag); +static void (APIENTRYP bf_glPolygonMode)(GLenum face, GLenum mode); +static void (APIENTRYP bf_glBlendFunc)(GLenum sfactor, GLenum dfactor); +static void (APIENTRYP bf_glScissor)(GLint x, GLint y, GLsizei width, GLsizei height); +static void (APIENTRYP bf_glViewport)(GLint x, GLint y, GLsizei width, GLsizei height); +static void (APIENTRYP bf_glFramebufferTexture)(GLenum target, GLenum attachment, GLuint texture, GLint level); +static void (APIENTRYP bf_glDrawBuffers)(GLsizei n, const GLenum *bufs); +static GLenum (APIENTRYP bf_glCheckFramebufferStatus)(GLenum target); +static void (APIENTRYP bf_glTexSubImage2D)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *pixels); +static void (APIENTRYP bf_glBindFramebuffer)(GLenum target, GLuint framebuffer); +static void (APIENTRYP bf_glClearColor)(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha); +static void (APIENTRYP bf_glClearDepth)(GLdouble depth); +static void (APIENTRYP bf_glClear)(GLbitfield mask); + #if !defined BF_PLATFORM_OPENGL_ES2 static void (APIENTRYP bf_glGetVertexAttribdv)(GLuint index, GLenum pname, GLdouble *params); #endif +enum class DebugSource : uint32 +{ + API = 0x8246, + WindowSystem = 0x8247, + ShaderCompiler = 0x8248, + ThirdParty = 0x8249, + Application = 0x824A, + Other = 0x824B +}; + +enum class DebugType : uint32 +{ + Error = 0x824C, + DeprecatedBehavior = 0x824D, + UndefinedBehavior = 0x824E, + Portability = 0x824F, + Performance = 0x8250, + Other = 0x8251, + Marker = 0x8268, +}; + +enum class DebugSeverity : uint32 +{ + High = 0x9146, + Medium = 0x9147, + Low = 0x9148, + Notification = 0x826B +}; + +typedef void(*DEBUGPROC)(DebugSource source, DebugType type, uint32 id, DebugSeverity severity, uint32 length, char* message, void* userParam); +static void (APIENTRYP bf_glDebugMessageCallback)(DEBUGPROC fn, void* userdata); + +static void APIENTRY DebugMessageCallback(DebugSource source, DebugType type, uint32 id, DebugSeverity severity, uint32 length, char* message, void* userParam) +{ + if (type == DebugType::Marker || severity == DebugSeverity::Notification) + return; + + switch (type) + { + case DebugType::Error: + OutputDebugStr("[Error] "); + break; + case DebugType::DeprecatedBehavior: + OutputDebugStr("[DeprecatedBehavior] "); + break; + + case DebugType::UndefinedBehavior: + OutputDebugStr("[UndefinedBehavior] "); + break; + + case DebugType::Portability: + OutputDebugStr("[Portability] "); + break; + + case DebugType::Performance: + OutputDebugStr("[Performance] "); + break; + + case DebugType::Other: + OutputDebugStr("[Other] "); + break; + + case DebugType::Marker: + OutputDebugStr("[Marker] "); + break; + } + + OutputDebugStr(message); + OutputDebugStrF(" %d\n", id); +} + /// static int GetPowerOfTwo(int input) @@ -223,11 +320,17 @@ void GLTexture::Blt(ImageData* imageData, int x, int y) } else { - glBindTexture(GL_TEXTURE_2D, mGLTexture); - glTexSubImage2D(GL_TEXTURE_2D, 0, x, y, imageData->mWidth, imageData->mHeight, GL_RGBA, GL_UNSIGNED_BYTE, imageData->mBits); + bf_glBindTexture(GL_TEXTURE_2D, mGLTexture); + bf_glTexSubImage2D(GL_TEXTURE_2D, 0, x, y, imageData->mWidth, imageData->mHeight, GL_RGBA, GL_UNSIGNED_BYTE, imageData->mBits); } } +void GLTexture::SetBits(int destX, int destY, int destWidth, int destHeight, int srcPitch, uint32 *bits) +{ + bf_glBindTexture(GL_TEXTURE_2D, mGLTexture); + bf_glTexSubImage2D(GL_TEXTURE_2D, 0, destX, destY, destWidth, destHeight, GL_RGBA, GL_UNSIGNED_BYTE, bits); +} + /// GLDrawBatch::GLDrawBatch() : DrawBatch() @@ -241,13 +344,6 @@ GLDrawBatch::~GLDrawBatch() extern int gBFDrawBatchCount; -struct GLVertex3D -{ - float x, y, z; - float u, v; - uint32 color; -}; - void GLDrawBatch::Render(RenderDevice* renderDevice, RenderWindow* renderWindow) { if (mIdxIdx == 0) @@ -260,34 +356,35 @@ void GLDrawBatch::Render(RenderDevice* renderDevice, RenderWindow* renderWindow) if (glRenderDevice->mGLVAO == 0) { + if (glRenderDevice->mGLVertexBuffer == 0) + { + bf_glGenBuffers(1, &glRenderDevice->mGLVertexBuffer); + bf_glGenBuffers(1, &glRenderDevice->mGLIndexBuffer); + } + + bf_glBindBuffer(GL_ARRAY_BUFFER, glRenderDevice->mGLVertexBuffer); bf_glGenVertexArrays(1, &glRenderDevice->mGLVAO); bf_glBindVertexArray(glRenderDevice->mGLVAO); - bf_glGenBuffers(1, &glRenderDevice->mGLVertexBuffer); - bf_glGenBuffers(1, &glRenderDevice->mGLIndexBuffer); + bf_glEnableVertexAttribArray(curShader->mAttribPosition); + bf_glVertexAttribPointer(curShader->mAttribPosition, 3, GL_FLOAT, GL_FALSE, sizeof(DefaultVertex3D), (void*)offsetof(DefaultVertex3D, x)); + bf_glEnableVertexAttribArray(curShader->mAttribTexCoord0); + bf_glVertexAttribPointer(curShader->mAttribTexCoord0, 2, GL_FLOAT, GL_FALSE, sizeof(DefaultVertex3D), (void*)offsetof(DefaultVertex3D, u)); + bf_glEnableVertexAttribArray(curShader->mAttribColor); + bf_glVertexAttribPointer(curShader->mAttribColor, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(DefaultVertex3D), (void*)offsetof(DefaultVertex3D, color)); } - - auto glVertices = (GLVertex3D*)mVertices; + bf_glBindVertexArray(glRenderDevice->mGLVAO); + auto glVertices = (DefaultVertex3D*)mVertices; bf_glBindBuffer(GL_ARRAY_BUFFER, glRenderDevice->mGLVertexBuffer); - bf_glBufferData(GL_ARRAY_BUFFER, mVtxIdx * sizeof(GLVertex3D), mVertices, GL_STREAM_DRAW); - - bf_glEnableVertexAttribArray(curShader->mAttribPosition); - bf_glVertexAttribPointer(curShader->mAttribPosition, 3, GL_FLOAT, GL_FALSE, sizeof(GLVertex3D), (void*)offsetof(GLVertex3D, x)); - bf_glEnableVertexAttribArray(curShader->mAttribTexCoord0); - bf_glVertexAttribPointer(curShader->mAttribTexCoord0, 2, GL_FLOAT, GL_FALSE, sizeof(GLVertex3D), (void*)offsetof(GLVertex3D, u)); - bf_glEnableVertexAttribArray(curShader->mAttribColor); - bf_glVertexAttribPointer(curShader->mAttribColor, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(GLVertex3D), (void*)offsetof(GLVertex3D, color)); + bf_glBufferData(GL_ARRAY_BUFFER, mVtxIdx * sizeof(DefaultVertex3D), mVertices, GL_STREAM_DRAW); + bf_glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, glRenderDevice->mGLIndexBuffer); + bf_glBufferData(GL_ELEMENT_ARRAY_BUFFER, mIdxIdx * sizeof(int16), mIndices, GL_STREAM_DRAW); if (mRenderState != renderDevice->mPhysRenderState) renderDevice->PhysSetRenderState(mRenderState); - bf_glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, glRenderDevice->mGLIndexBuffer); - bf_glBufferData(GL_ELEMENT_ARRAY_BUFFER, mIdxIdx * sizeof(int16), mIndices, GL_STREAM_DRAW); bf_glDrawElements(GL_TRIANGLES, mIdxIdx, GL_UNSIGNED_SHORT, NULL); - - bf_glBufferData(GL_ELEMENT_ARRAY_BUFFER, 0, NULL, GL_STREAM_DRAW); - bf_glBufferData(GL_ARRAY_BUFFER, 0, NULL, GL_STREAM_DRAW); } GLDrawLayer::GLDrawLayer() @@ -339,16 +436,11 @@ static void BFGetGLProc(T& proc, const char* name) #define BF_GET_GLPROC(name) BFGetGLProc(bf_##name, #name) -void GL_DebugCallback(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar* message, const void* userParam) -{ - NOP; -} - GLRenderWindow::GLRenderWindow(GLRenderDevice* renderDevice, SDL_Window* sdlWindow) { if (bf_glGenBuffers == NULL) { - BF_GET_GLPROC(glDebugMessageCallback); + BF_GET_GLPROC(glGetError); BF_GET_GLPROC(glActiveTexture); BF_GET_GLPROC(glGenVertexArrays); BF_GET_GLPROC(glBindVertexArray); @@ -409,11 +501,49 @@ GLRenderWindow::GLRenderWindow(GLRenderDevice* renderDevice, SDL_Window* sdlWind BF_GET_GLPROC(glGetObjectParameterivARB); BF_GET_GLPROC(glCompressedTexImage2D); BF_GET_GLPROC(glClientActiveTexture); + BF_GET_GLPROC(glGenTextures); + BF_GET_GLPROC(glBindTexture); + BF_GET_GLPROC(glPixelStorei); + BF_GET_GLPROC(glTexImage2D); + BF_GET_GLPROC(glTexParameteri); + BF_GET_GLPROC(glDisable); + BF_GET_GLPROC(glEnable); + BF_GET_GLPROC(glCullFace); + BF_GET_GLPROC(glDepthMask); + BF_GET_GLPROC(glPolygonMode); + BF_GET_GLPROC(glDepthFunc); + BF_GET_GLPROC(glBlendFunc); + BF_GET_GLPROC(glScissor); + BF_GET_GLPROC(glViewport); + BF_GET_GLPROC(glFramebufferTexture); + BF_GET_GLPROC(glDrawBuffers); + BF_GET_GLPROC(glCheckFramebufferStatus); + BF_GET_GLPROC(glTexSubImage2D); + BF_GET_GLPROC(glBindFramebuffer); + BF_GET_GLPROC(glClearColor); + BF_GET_GLPROC(glClearDepth); + BF_GET_GLPROC(glClear); #if !defined BF_PLATFORM_OPENGL_ES2 BF_GET_GLPROC(glGetVertexAttribdv); #endif - } + +#if defined(_DEBUG) && !defined(BF_PLATFORM_OPENGL_ES2) + + BF_GET_GLPROC(glDebugMessageCallback); + if (bf_glDebugMessageCallback != NULL) + { + bf_glEnable(GL_DEBUG_OUTPUT); + bf_glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS); + bf_glDebugMessageCallback(&DebugMessageCallback, NULL); + } +#endif + + } + +#ifndef BF_PLATFORM_OPENGL_ES2 + //glEnableClientState(GL_INDEX_ARRAY); +#endif mSDLWindow = sdlWindow; mRenderDevice = renderDevice; @@ -429,12 +559,25 @@ GLRenderWindow::~GLRenderWindow() void GLRenderWindow::PhysSetAsTarget() { - bf_SDL_GL_MakeCurrent(mSDLWindow, ((SdlBFApp*)gBFApp)->mGLContext ); + bf_SDL_GL_MakeCurrent(mSDLWindow, ((SdlBFApp*)gBFApp)->mGLContext); + + bf_glEnable(GL_BLEND); + bf_glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); - GLfloat matrix[4][4]; - CreateOrthographicOffCenter(0.0f, (float)mWidth, (float)mHeight, 0.0f, -100.0f, 100.0f, matrix); - glViewport(0, 0, (GLsizei)mWidth, (GLsizei)mHeight); + if (mResizePending) + { + Resized(); + } + bf_glViewport(0, 0, (GLsizei)mWidth, (GLsizei)mHeight); + bf_glScissor(0, 0, (GLsizei)mWidth, (GLsizei)mHeight); + + if (!mHasBeenDrawnTo) + { + bf_glClearColor(0, 0, 0, 0); + bf_glClearDepth(1); + bf_glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + } mHasBeenDrawnTo = true; } @@ -443,7 +586,6 @@ void GLRenderWindow::SetAsTarget() //TODO: Handle this more elegantly when we actually handle draw layers properly... //if (mRenderDevice->mCurRenderTarget != NULL) //mRenderDevice->mCurDrawLayer->Flush(); - bf_SDL_GL_MakeCurrent(mSDLWindow, ((SdlBFApp*)gBFApp)->mGLContext ); mHasBeenTargeted = true; mRenderDevice->mCurRenderTarget = this; @@ -454,70 +596,38 @@ void GLRenderWindow::Resized() mRenderDevice->mResizeCount++; mResizeNum = mRenderDevice->mResizeCount; - bf_SDL_GetWindowSize(mSDLWindow, &mWidth, &mHeight); - - //NOT_IMPL; - /*if (mGLSwapChain != NULL) - { - mGLRenderTargetView->Release(); - mGLBackBuffer->Release(); - GLCHECK(mGLSwapChain->ResizeBuffers(1, mWidth, mHeight, GLGI_FORMAT_R8G8B8A8_UNORM, 0)); - - GLCHECK(mGLSwapChain->GetBuffer(0, __uuidof(IGL10Texture2D), (LPVOID*)&mGLBackBuffer)); - GLCHECK(mRenderDevice->mGLDevice->CreateRenderTargetView(mGLBackBuffer, NULL, &mGLRenderTargetView)); - }*/ + bf_SDL_GetWindowSizeInPixels(mSDLWindow, &mWidth, &mHeight); + mResizePending = false; } void GLRenderWindow::Present() { bf_SDL_GL_SwapWindow(mSDLWindow); - //GLCHECK(mGLSwapChain->Present((mWindow->mFlags & BFWINDOW_VSYNC) ? 1 : 0, 0)); } void GLRenderWindow::CopyBitsTo(uint32* dest, int width, int height) { mCurDrawLayer->Flush(); - NOT_IMPL; - /*GL10_TEXTURE2D_DESC texDesc; - texDesc.ArraySize = 1; - texDesc.BindFlags = 0; - texDesc.CPUAccessFlags = 0; - texDesc.Format = GLGI_FORMAT_R8G8B8A8_UNORM; - texDesc.Width = width; - texDesc.Height = height; - texDesc.MipLevels = 1; - texDesc.MiscFlags = 0; - texDesc.SampleDesc.Count = 1; - texDesc.SampleDesc.Quality = 0; - texDesc.Usage = GL10_USAGE_STAGING; - texDesc.CPUAccessFlags = GL10_CPU_ACCESS_READ; - - IGL10Texture2D *texture; - GLCHECK(mRenderDevice->mGLDevice->CreateTexture2D(&texDesc, 0, &texture)); - mRenderDevice->mGLDevice->CopyResource(texture, mGLBackBuffer); - - GL10_MAPPED_TEXTURE2D mapTex; - GLCHECK(texture->Map(GL10CalcSubresource(0, 0, 1), GL10_MAP_READ, 0, &mapTex)); - uint8* srcPtr = (uint8*) mapTex.pData; - uint8* destPtr = (uint8*) dest; - for (int y = 0; y < height; y++) - { - memcpy(destPtr, srcPtr, width*sizeof(uint32)); - srcPtr += mapTex.RowPitch; - destPtr += width * 4; - } - texture->Unmap(0); - texture->Release();*/ +} + +float GLRenderWindow::GetRefreshRate() +{ + SDL_DisplayID displayID = bf_SDL_GetDisplayForWindow(mSDLWindow); + const SDL_DisplayMode *mode = bf_SDL_GetCurrentDisplayMode(displayID); + + if (mode != NULL) + return mode->refresh_rate; + + return RenderWindow::GetRefreshRate(); } /// GLRenderDevice::GLRenderDevice() { - //mGLDevice = NULL; mCurShader = NULL; - mGLVAO = 0; + mGLVAO = 0; mGLVertexBuffer = 0; mGLIndexBuffer = 0; mBlankTexture = 0; @@ -532,84 +642,22 @@ bool GLRenderDevice::Init(BFApp* app) { SdlBFApp* winApp = (SdlBFApp*) app; - //RenderState* glRenderState; - if (mDefaultRenderState == NULL) - { - auto dxRenderState = (RenderState*)CreateRenderState(NULL); - - mDefaultRenderState = dxRenderState; - mDefaultRenderState->mDepthFunc = DepthFunc_Less; - mDefaultRenderState->mWriteDepthBuffer = true; - - mPhysRenderState = mDefaultRenderState; - } - else - { - //glRenderState = (DXRenderState*)mDefaultRenderState; - //glRenderState->ReinitNative(); - } - - /// - - ////Use GL10_CREATE_DEVICE_DEBUG for PIX - //GLCHECK(GL10CreateDevice(NULL, GL10_DRIVER_TYPE_HARDWARE, NULL, GL10_CREATE_DEVICE_DEBUG, GL10_SDK_VERSION, &mGLDevice)); - ////GLCHECK(GL10CreateDevice(NULL, GL10_DRIVER_TYPE_HARDWARE, NULL, 0, GL10_SDK_VERSION, &mGLDevice)); - - //IGLGIDevice* pGLGIDevice = NULL; - //GLCHECK(mGLDevice->QueryInterface(__uuidof(IGLGIDevice), reinterpret_cast(&pGLGIDevice))); - - //IGLGIAdapter* pGLGIAdapter = NULL; - //GLCHECK(pGLGIDevice->GetParent(__uuidof(IGLGIAdapter), reinterpret_cast(&pGLGIAdapter))); - - //IGLGIFactory* pGLGIFactory = NULL; - //GLCHECK(pGLGIAdapter->GetParent(__uuidof(IGLGIFactory), reinterpret_cast(&mGLGIFactory))); - - ////set rasterizer - //GL10_RASTERIZER_DESC rasterizerState; - //rasterizerState.CullMode = GL10_CULL_NONE; - //rasterizerState.FillMode = GL10_FILL_SOLID; - //rasterizerState.FrontCounterClockwise = true; - // rasterizerState.DepthBias = false; - // rasterizerState.DepthBiasClamp = 0; - // rasterizerState.SlopeScaledDepthBias = 0; - // rasterizerState.DepthClipEnable = false; - // rasterizerState.ScissorEnable = true; - // //TODO:rasterizerState.MultisampleEnable = false; - //rasterizerState.MultisampleEnable = true; - // rasterizerState.AntialiasedLineEnable = true; - // - //mGLDevice->CreateRasterizerState( &rasterizerState, &mGLRasterizerStateClipped); - // - //rasterizerState.ScissorEnable = false; - //mGLDevice->CreateRasterizerState( &rasterizerState, &mGLRasterizerStateUnclipped); - //mGLDevice->RSSetState(mGLRasterizerStateUnclipped); - // - //IGL10BlendState* g_pBlendState = NULL; - - //GL10_BLEND_DESC BlendState; - //ZeroMemory(&BlendState, sizeof(GL10_BLEND_DESC)); - //BlendState.BlendEnable[0] = TRUE; - ////BlendState.SrcBlend = GL10_BLEND_SRC_ALPHA; - //BlendState.SrcBlend = GL10_BLEND_ONE; + BF_ASSERT(mDefaultRenderState == NULL); + auto renderState = (RenderState*)CreateRenderState(NULL); - //BlendState.DestBlend = GL10_BLEND_INV_SRC_ALPHA; - //BlendState.BlendOp = GL10_BLEND_OP_ADD; - //BlendState.SrcBlendAlpha = GL10_BLEND_ONE; - //BlendState.DestBlendAlpha = GL10_BLEND_ONE; - //BlendState.BlendOpAlpha = GL10_BLEND_OP_ADD; - //BlendState.RenderTargetWriteMask[0] = GL10_COLOR_WRITE_ENABLE_ALL; - //mGLDevice->CreateBlendState(&BlendState, &mGLNormalBlendState); - - //BlendState.DestBlend = GL10_BLEND_ONE; - //mGLDevice->CreateBlendState(&BlendState, &mGLAdditiveBlendState); - - //PhysSetAdditive(false); + mDefaultRenderState = renderState; + mDefaultRenderState->mDepthFunc = DepthFunc_Less; + mDefaultRenderState->mWriteDepthBuffer = true; + mPhysRenderState = mDefaultRenderState; return true; } void GLRenderDevice::FrameStart() { + if (mRenderWindowList.IsEmpty()) + return; + mCurRenderTarget = NULL; mPhysRenderWindow = NULL; @@ -618,6 +666,10 @@ void GLRenderDevice::FrameStart() aRenderWindow->mHasBeenDrawnTo = false; aRenderWindow->mHasBeenTargeted = false; } + + bf_glDisable(GL_SCISSOR_TEST); + bf_glDisable(GL_CULL_FACE); + bf_glDisable(GL_DEPTH_TEST); } void GLRenderDevice::FrameEnd() @@ -661,7 +713,7 @@ Shader* GLRenderDevice::LoadShader(const StringImpl& fileName, VertexDefinition* { GLShader* glShader = new GLShader(); - glShader->mVertexSize = sizeof(GLVertex3D); + glShader->mVertexSize = sizeof(DefaultVertex3D); glShader->mGLVertexShader = bf_glCreateShader(GL_VERTEX_SHADER); glShader->mGLFragmentShader = bf_glCreateShader(GL_FRAGMENT_SHADER); @@ -716,6 +768,7 @@ Shader* GLRenderDevice::LoadShader(const StringImpl& fileName, VertexDefinition* glShader->mAttribColor = bf_glGetAttribLocation(glShader->mGLProgram, "color"); glShader->mAttribTex0 = bf_glGetUniformLocation(glShader->mGLProgram, "tex"); glShader->mAttribTex1 = bf_glGetUniformLocation(glShader->mGLProgram, "tex2"); + glShader->mScreenUniformLoc = bf_glGetUniformLocation(glShader->mGLProgram, "screenMatrix"); return glShader; } @@ -726,29 +779,90 @@ void GLRenderDevice::PhysSetRenderState(RenderState* renderState) if (mCurShader != NULL) { bf_glUseProgram(mCurShader->mGLProgram); - - GLRenderDevice* aRenderDevice = (GLRenderDevice*)gBFApp->mRenderDevice; - - //TODO: Cache more - - GLfloat matrix[4][4]; - CreateOrthographicOffCenter(0.0f, (float)mPhysRenderWindow->mWidth, (float)mPhysRenderWindow->mHeight, 0.0f, -100.0f, 100.0f, matrix); - GLint matrixLoc = bf_glGetUniformLocation(mCurShader->mGLProgram, "screenMatrix"); - //BF_ASSERT(matrixLoc >= 0); - if (matrixLoc >= 0) - bf_glUniformMatrix4fv(matrixLoc, 1, false, (float*)matrix); + if (mCurShader->mScreenUniformLoc >= 0) + { + GLfloat matrix[4][4]; + CreateOrthographicOffCenter(0.0f, (float)mPhysRenderWindow->mWidth, (float)mPhysRenderWindow->mHeight, 0.0f, -100.0f, 100.0f, matrix); + bf_glUniformMatrix4fv(mCurShader->mScreenUniformLoc, 1, false, (float*)matrix); + } } if (renderState->mClipped) { - glEnable(GL_SCISSOR_TEST); - glScissor((GLsizei)renderState->mClipRect.x, - mPhysRenderWindow->mHeight - (GLsizei)renderState->mClipRect.y - (GLsizei)renderState->mClipRect.height, - (GLsizei)renderState->mClipRect.width, (GLsizei)renderState->mClipRect.height); + bf_glEnable(GL_SCISSOR_TEST); + bf_glScissor((GLsizei)renderState->mClipRect.x, + mPhysRenderWindow->mHeight - (GLsizei)renderState->mClipRect.y - (GLsizei)renderState->mClipRect.height, + (GLsizei)renderState->mClipRect.width, (GLsizei)renderState->mClipRect.height); } else { - glDisable(GL_SCISSOR_TEST); + bf_glDisable(GL_SCISSOR_TEST); + } + + if (renderState->mCullMode != mPhysRenderState->mCullMode) + { + switch (renderState->mCullMode) + { + case CullMode_None: + bf_glDisable(GL_CULL_FACE); + break; + case CullMode_Front: + bf_glEnable(GL_CULL_FACE); + bf_glCullFace(GL_FRONT); + break; + case CullMode_Back: + bf_glEnable(GL_CULL_FACE); + bf_glCullFace(GL_BACK); + break; + } + } + + if (renderState->mDepthFunc != mPhysRenderState->mDepthFunc) + { + bf_glDepthMask(renderState->mWriteDepthBuffer ? GL_TRUE : GL_FALSE); + + switch (renderState->mDepthFunc) + { + case DepthFunc_Never: + bf_glDisable(GL_DEPTH_TEST); + break; + case DepthFunc_Less: + bf_glDepthFunc(GL_LESS); + bf_glEnable(GL_DEPTH_TEST); + break; + case DepthFunc_LessEqual: + bf_glDepthFunc(GL_LEQUAL); + bf_glEnable(GL_DEPTH_TEST); + break; + case DepthFunc_Equal: + bf_glDepthFunc(GL_EQUAL); + bf_glEnable(GL_DEPTH_TEST); + break; + case DepthFunc_Greater: + bf_glDepthFunc(GL_GREATER); + bf_glEnable(GL_DEPTH_TEST); + break; + case DepthFunc_NotEqual: + bf_glDepthFunc(GL_NOTEQUAL); + bf_glEnable(GL_DEPTH_TEST); + break; + case DepthFunc_GreaterEqual: + bf_glDepthFunc(GL_GEQUAL); + bf_glEnable(GL_DEPTH_TEST); + break; + case DepthFunc_Always: + bf_glDepthFunc(GL_ALWAYS); + bf_glEnable(GL_DEPTH_TEST); + break; + } + } + + if ((renderState->mWireframe != mPhysRenderState->mWireframe)) + { + if (renderState->mWireframe) + bf_glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); + else + bf_glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); } mPhysRenderState = renderState; @@ -756,15 +870,56 @@ void GLRenderDevice::PhysSetRenderState(RenderState* renderState) Texture* GLRenderDevice::CreateRenderTarget(int width, int height, bool destAlpha) { + // GLTexture* texture = new GLTexture(); + // GLuint id; + // bf_glGenTextures(1, &id); + // bf_glBindTexture(GL_TEXTURE_2D, id); + // bf_glTexImage2D(GL_TEXTURE_2D, 0, (destAlpha ? GL_RGBA : GL_RGB), width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL); + // bf_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + // bf_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + // + // GLuint depthrenderbuffer; + // bf_glGenRenderbuffers(1, &depthrenderbuffer); + // bf_glBindRenderbuffer(GL_RENDERBUFFER, depthrenderbuffer); + // bf_glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, width, height); + // bf_glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depthrenderbuffer); + // texture->mGLTexture = id; + // texture->mGLTexture2 = depthrenderbuffer; + // texture->AddRef(); + // return texture; NOT_IMPL; } +Texture* GLRenderDevice::CreateDynTexture(int width, int height) +{ + auto context = bf_SDL_GL_GetCurrentContext(); + auto err = bf_SDL_GetError(); + GLuint texture = 0; + bf_glGenTextures(1, &texture); + auto result = bf_glGetError(); + + bf_glBindTexture(GL_TEXTURE_2D, texture); + bf_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + bf_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + bf_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + bf_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + bf_glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); + + GLTexture* glTexture = new GLTexture(); + glTexture->mGLTexture = texture; + glTexture->mGLTexture2 = 0; + glTexture->mRenderDevice = this; + glTexture->mWidth = width; + glTexture->mHeight = height; + glTexture->AddRef(); + return glTexture; +} + void GLRenderDevice::SetRenderState(RenderState* renderState) { mCurRenderState = renderState; } - void GLSetTextureCmd::Render(RenderDevice* renderDevice, RenderWindow* renderWindow) { /*#ifdef BF_PLATFORM_OPENGL_ES2 @@ -790,12 +945,12 @@ void GLSetTextureCmd::Render(RenderDevice* renderDevice, RenderWindow* renderWin if (glRenderDevice->mBlankTexture == 0) { - glGenTextures(1, &glRenderDevice->mBlankTexture); - glBindTexture(GL_TEXTURE_2D, glRenderDevice->mBlankTexture); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + bf_glGenTextures(1, &glRenderDevice->mBlankTexture); + bf_glBindTexture(GL_TEXTURE_2D, glRenderDevice->mBlankTexture); + bf_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + bf_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + bf_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + bf_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); /*if (bf_glCompressedTexImage2D != NULL) { @@ -806,10 +961,10 @@ void GLSetTextureCmd::Render(RenderDevice* renderDevice, RenderWindow* renderWin else*/ { uint16 color = 0; - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, + bf_glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4, &color); } - glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + bf_glPixelStorei(GL_UNPACK_ALIGNMENT, 1); } if (glTexture->mImageData != NULL) @@ -822,12 +977,12 @@ void GLSetTextureCmd::Render(RenderDevice* renderDevice, RenderWindow* renderWin for (int texNum = 0; texNum < 2/*texCount*/; texNum++) { GLuint glTextureID; - glGenTextures(1, &glTextureID); - glBindTexture(GL_TEXTURE_2D, glTextureID); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + bf_glGenTextures(1, &glTextureID); + bf_glBindTexture(GL_TEXTURE_2D, glTextureID); + bf_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + bf_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + bf_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + bf_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); //if (imageData->mHWBits != NULL) //{ @@ -842,11 +997,11 @@ void GLSetTextureCmd::Render(RenderDevice* renderDevice, RenderWindow* renderWin //} //else { - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, glTexture->mImageData->mWidth, glTexture->mImageData->mHeight, 0, + bf_glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, glTexture->mImageData->mWidth, glTexture->mImageData->mHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, glTexture->mImageData->mBits); } - glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + bf_glPixelStorei(GL_UNPACK_ALIGNMENT, 1); if (texNum == 0) glTexture->mGLTexture = glTextureID; @@ -860,5 +1015,5 @@ void GLSetTextureCmd::Render(RenderDevice* renderDevice, RenderWindow* renderWin bf_glActiveTexture(GL_TEXTURE0 + mTextureIdx); //glUniform1i(curShader->mAttribTex0, 0); - glBindTexture(GL_TEXTURE_2D, glTexture->mGLTexture); + bf_glBindTexture(GL_TEXTURE_2D, glTexture->mGLTexture); } diff --git a/BeefySysLib/platform/sdl/GLRenderDevice.h b/BeefySysLib/platform/sdl/GLRenderDevice.h index db072d50f..76219638b 100644 --- a/BeefySysLib/platform/sdl/GLRenderDevice.h +++ b/BeefySysLib/platform/sdl/GLRenderDevice.h @@ -28,14 +28,14 @@ class GLTexture : public Texture GLuint mGLTexture; GLuint mGLTexture2; ImageData* mImageData; - //IGL10RenderTargetView* mGLRenderTargetView; public: GLTexture(); - ~GLTexture(); + virtual ~GLTexture(); - virtual void PhysSetAsTarget(); + virtual void PhysSetAsTarget() override; virtual void Blt(ImageData* imageData, int x, int y) override; + virtual void SetBits(int destX, int destY, int destWidth, int destHeight, int srcPitch, uint32 *bits) override; }; class GLShaderParam : public ShaderParam @@ -47,7 +47,7 @@ class GLShaderParam : public ShaderParam GLShaderParam(); ~GLShaderParam(); - virtual void SetTexture(Texture* texture); + virtual void SetTexture(Texture* texture) override; virtual void SetFloat4(float x, float y, float z, float w) override; }; @@ -56,18 +56,17 @@ typedef Dictionary GLShaderParamMap; class GLShader : public Shader { public: - //IGL10Effect* mGLEffect; - - GLuint mGLVertexShader; - GLuint mGLFragmentShader; - GLuint mGLProgram; - GLint mAttribPosition; - GLint mAttribTexCoord0; - GLint mAttribColor; - GLint mAttribTex0; - GLint mAttribTex1; + GLuint mGLVertexShader; + GLuint mGLFragmentShader; + GLuint mGLProgram; + GLint mAttribPosition; + GLint mAttribTexCoord0; + GLint mAttribColor; + GLint mAttribTex0; + GLint mAttribTex1; + GLint mScreenUniformLoc; - GLShaderParamMap mParamsMap; + GLShaderParamMap mParamsMap; public: GLShader(); @@ -90,7 +89,7 @@ class GLSetTextureCmd : public RenderCmd class GLDrawBatch : public DrawBatch { public: - //IGL10Buffer* mGLBuffer; + public: GLDrawBatch(); @@ -126,13 +125,14 @@ class GLRenderWindow : public RenderWindow public: GLRenderWindow(GLRenderDevice* renderDevice, SDL_Window* sdlWindow); - ~GLRenderWindow(); + virtual ~GLRenderWindow(); void SetAsTarget() override; void Resized() override; - virtual void Present() override; + void Present() override; void CopyBitsTo(uint32* dest, int width, int height); + float GetRefreshRate() override; }; class GLRenderDevice : public RenderDevice @@ -167,7 +167,7 @@ class GLRenderDevice : public RenderDevice Shader* LoadShader(const StringImpl& fileName, VertexDefinition* vertexDefinition) override; Texture* CreateRenderTarget(int width, int height, bool destAlpha) override; - virtual Texture* CreateDynTexture(int width, int height) override { return NULL; } + virtual Texture* CreateDynTexture(int width, int height) override; virtual void SetRenderState(RenderState* renderState) override; /*void SetShader(Shader* shader) override; diff --git a/BeefySysLib/platform/sdl/SdlBFApp.cpp b/BeefySysLib/platform/sdl/SdlBFApp.cpp index 90c62da26..428517278 100644 --- a/BeefySysLib/platform/sdl/SdlBFApp.cpp +++ b/BeefySysLib/platform/sdl/SdlBFApp.cpp @@ -37,6 +37,8 @@ void (SDLCALL* bf_SDL_memset)(void* dest, int c, size_t len); void* (SDLCALL* bf_SDL_memcpy)(void *dst, const void *src, size_t len); SDL_PropertiesID (SDLCALL* bf_SDL_CreateProperties)(void); +void (SDLCALL* bf_SDL_DestroyProperties)(SDL_PropertiesID props); + bool (SDLCALL* bf_SDL_SetNumberProperty)(SDL_PropertiesID props, const char* name, int64_t value); bool (SDLCALL* bf_SDL_SetBooleanProperty)(SDL_PropertiesID props, const char* name, bool value); bool (SDLCALL* bf_SDL_SetStringProperty)(SDL_PropertiesID props, const char* name, const char* value); @@ -45,8 +47,10 @@ bool (SDLCALL* bf_SDL_SetPointerProperty)(SDL_PropertiesID props, const char *na SDL_Window* (SDLCALL* bf_SDL_CreateWindowWithProperties)(SDL_PropertiesID props); SDL_WindowID (SDLCALL* bf_SDL_GetWindowID)(SDL_Window* window); void (SDLCALL* bf_SDL_DestroyWindow)(SDL_Window* window); +bool (SDLCALL* bf_SDL_SyncWindow)(SDL_Window* window); bool (SDLCALL* bf_SDL_GetWindowPosition)(SDL_Window* window,int* x, int* y); bool (SDLCALL* bf_SDL_SetWindowPosition)(SDL_Window* window, int x, int y); +bool (SDLCALL* bf_SDL_GetWindowSizeInPixels)(SDL_Window* window, int* w, int* h); bool (SDLCALL* bf_SDL_GetWindowSize)(SDL_Window* window, int* w, int* h); bool (SDLCALL* bf_SDL_SetWindowSize)(SDL_Window* window, int w, int h); bool (SDLCALL* bf_SDL_SetWindowMinimumSize)(SDL_Window* window, int min_w, int min_h); @@ -78,10 +82,14 @@ SDL_DisplayID* (SDLCALL* bf_SDL_GetDisplays)(int* count); bool (SDLCALL* bf_SDL_GetDisplayBounds)(SDL_DisplayID displayID, SDL_Rect* rect); SDL_DisplayMode* (SDLCALL* bf_SDL_GetDesktopDisplayMode)(SDL_DisplayID displayID); bool (SDLCALL* bf_SDL_HasRectIntersection)(const SDL_Rect* A, const SDL_Rect* B); +SDL_DisplayID (SDLCALL* bf_SDL_GetDisplayForWindow)(SDL_Window *window); +const SDL_DisplayMode* (SDLCALL* bf_SDL_GetCurrentDisplayMode)(SDL_DisplayID displayID); SDL_Surface* (SDLCALL* bf_SDL_CreateSurfaceFrom)(int width, int height, SDL_PixelFormat format, void *pixels, int pitch); SDL_GLContext (SDLCALL* bf_SDL_GL_CreateContext)(SDL_Window* window); +SDL_GLContext (SDLCALL* bf_SDL_GL_GetCurrentContext)(); +SDL_Window* (SDLCALL* bf_SDL_GL_GetCurrentWindow)(); bool (SDLCALL* bf_SDL_GL_MakeCurrent)(SDL_Window* window, SDL_GLContext context); bool (SDLCALL* bf_SDL_GL_SetAttribute)(SDL_GLAttr attr, int value); void* (SDLCALL* bf_SDL_GL_GetProcAddress)(const char* proc); @@ -90,6 +98,13 @@ bool (SDLCALL* bf_SDL_GL_SwapWindow)(SDL_Window* window); static SDL_Cursor* (SDLCALL* bf_SDL_GetDefaultCursor)(); static SDL_Cursor* (SDLCALL* bf_SDL_CreateSystemCursor)(SDL_SystemCursor id); static bool (SDLCALL* bf_SDL_SetCursor)(SDL_Cursor* cursor); +static SDL_WindowFlags (SDLCALL* bf_SDL_GetWindowFlags)(SDL_Window *window); +static bool (SDLCALL* bf_SDL_HideWindow)(SDL_Window *window); +static bool (SDLCALL* bf_SDL_RestoreWindow)(SDL_Window *window); +static bool (SDLCALL* bf_SDL_MinimizeWindow)(SDL_Window *window); +static bool (SDLCALL* bf_SDL_MaximizeWindow)(SDL_Window *window); +static bool (SDLCALL* bf_SDL_ShowWindow)(SDL_Window *window); +static bool (SDLCALL* bf_SDL_RaiseWindow)(SDL_Window* window); struct AdjustedMonRect { @@ -161,21 +176,21 @@ SdlBFWindow::SdlBFWindow(BFWindow* parent, const StringImpl& title, int x, int y SDL_PropertiesID props = bf_SDL_CreateProperties(); bf_SDL_SetBooleanProperty(props, SDL_PROP_WINDOW_CREATE_OPENGL_BOOLEAN, true); - bf_SDL_SetBooleanProperty(props, SDL_PROP_WINDOW_CREATE_RESIZABLE_BOOLEAN, (windowFlags & BFWINDOW_RESIZABLE) > 0); - bf_SDL_SetBooleanProperty(props, SDL_PROP_WINDOW_CREATE_FULLSCREEN_BOOLEAN, (windowFlags & BFWINDOW_FULLSCREEN) > 0); + bf_SDL_SetBooleanProperty(props, SDL_PROP_WINDOW_CREATE_RESIZABLE_BOOLEAN, (windowFlags & BFWINDOW_RESIZABLE) != 0); + bf_SDL_SetBooleanProperty(props, SDL_PROP_WINDOW_CREATE_FULLSCREEN_BOOLEAN, (windowFlags & BFWINDOW_FULLSCREEN) != 0); bf_SDL_SetBooleanProperty(props, SDL_PROP_WINDOW_CREATE_BORDERLESS_BOOLEAN, (windowFlags & BFWINDOW_BORDER) == 0); - bf_SDL_SetBooleanProperty(props, SDL_PROP_WINDOW_CREATE_TOOLTIP_BOOLEAN, (windowFlags & BFWINDOW_TOOLTIP) > 0); - bf_SDL_SetBooleanProperty(props, SDL_PROP_WINDOW_CREATE_TRANSPARENT_BOOLEAN, (windowFlags & BFWINDOW_DEST_ALPHA) > 0); - bf_SDL_SetBooleanProperty(props, SDL_PROP_WINDOW_CREATE_MENU_BOOLEAN, (windowFlags & BFWINDOW_FAKEFOCUS) > 0); + bf_SDL_SetBooleanProperty(props, SDL_PROP_WINDOW_CREATE_TOOLTIP_BOOLEAN, (windowFlags & BFWINDOW_TOOLTIP) != 0); + bf_SDL_SetBooleanProperty(props, SDL_PROP_WINDOW_CREATE_TRANSPARENT_BOOLEAN, (windowFlags & BFWINDOW_DEST_ALPHA) != 0); + bf_SDL_SetBooleanProperty(props, SDL_PROP_WINDOW_CREATE_MENU_BOOLEAN, (windowFlags & BFWINDOW_FAKEFOCUS) != 0); bf_SDL_SetBooleanProperty(props, SDL_PROP_WINDOW_CREATE_FOCUSABLE_BOOLEAN, (windowFlags & BFWINDOW_FAKEFOCUS) == 0); - bf_SDL_SetBooleanProperty(props, SDL_PROP_WINDOW_CREATE_MODAL_BOOLEAN, (windowFlags & BFWINDOW_MODAL) > 0); - bf_SDL_SetBooleanProperty(props, SDL_PROP_WINDOW_CREATE_ALWAYS_ON_TOP_BOOLEAN, (windowFlags & BFWINDOW_TOPMOST) > 0); + bf_SDL_SetBooleanProperty(props, SDL_PROP_WINDOW_CREATE_MODAL_BOOLEAN, (windowFlags & BFWINDOW_MODAL) != 0); + bf_SDL_SetBooleanProperty(props, SDL_PROP_WINDOW_CREATE_ALWAYS_ON_TOP_BOOLEAN, (windowFlags & BFWINDOW_TOPMOST) != 0); if (parent != NULL) { SDL_Window* parentWindow = ((SdlBFWindow*)parent)->mSDLWindow; bf_SDL_SetPointerProperty(props, SDL_PROP_WINDOW_CREATE_PARENT_POINTER, parentWindow); - if ((windowFlags & BFWINDOW_TOOLTIP | BFWINDOW_FAKEFOCUS) > 0) // Tooltips and menus have relative positioning to their parent. + if ((windowFlags & BFWINDOW_TOOLTIP | BFWINDOW_FAKEFOCUS) != 0) // Tooltips and menus have relative positioning to their parent. { int parentX, parentY; bf_SDL_GetWindowPosition(parentWindow, &parentX, &parentY); @@ -197,6 +212,7 @@ SdlBFWindow::SdlBFWindow(BFWindow* parent, const StringImpl& title, int x, int y mSDLWindow = bf_SDL_CreateWindowWithProperties(props); + bf_SDL_DestroyProperties(props); // printf("Created %i : %s\n", bf_SDL_GetWindowID(mSDLWindow), title.c_str()); if (gAppIconSurface) @@ -204,14 +220,22 @@ SdlBFWindow::SdlBFWindow(BFWindow* parent, const StringImpl& title, int x, int y bf_SDL_StartTextInput(mSDLWindow); #ifndef BF_PLATFORM_OPENGL_ES2 + int contextFlags = SDL_GL_CONTEXT_PROFILE_CORE; +#ifdef _DEBUG + contextFlags |= SDL_GL_CONTEXT_DEBUG_FLAG; +#endif + bf_SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3); bf_SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 2); - bf_SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE); + bf_SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, contextFlags); #endif - if(((SdlBFApp*)gBFApp)->mGLContext == NULL) + auto sdlApp = (SdlBFApp*)gBFApp; + if(sdlApp->mGLContext == NULL) { - if (!(((SdlBFApp*)gBFApp)->mGLContext = bf_SDL_GL_CreateContext(mSDLWindow))) + sdlApp->mGLContextWindow = mSDLWindow; + sdlApp->mGLContext = bf_SDL_GL_CreateContext(mSDLWindow); + if (sdlApp->mGLContext == NULL) { String str = StrFormat( #ifdef BF_PLATFORM_OPENGL_ES2 @@ -228,18 +252,6 @@ SdlBFWindow::SdlBFWindow(BFWindow* parent, const StringImpl& title, int x, int y } } -#ifndef BF_PLATFORM_OPENGL_ES2 - glEnable(GL_DEBUG_OUTPUT); - glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS); -#endif - - glEnable(GL_BLEND); - glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); - -#ifndef BF_PLATFORM_OPENGL_ES2 - //glEnableClientState(GL_INDEX_ARRAY); -#endif - mIsMouseInside = false; mIsMouseVisible = true; mHasPositionInit = false; @@ -265,8 +277,17 @@ void SdlBFWindow::Destroy() SdlBFApp* app = (SdlBFApp*)gBFApp; app->mSdlWindowMap.Remove(bf_SDL_GetWindowID(mSDLWindow)); + SDL_Window* currentContextWindow = bf_SDL_GL_GetCurrentWindow(); + bf_SDL_StopTextInput(mSDLWindow); bf_SDL_DestroyWindow(mSDLWindow); + + // Make sure we have valid gl context in case we call any GL functions between frames + auto sdlApp = (SdlBFApp*)gBFApp; + if ((currentContextWindow == mSDLWindow) && (mSDLWindow != sdlApp->mGLContextWindow)) + { + bf_SDL_GL_MakeCurrent(sdlApp->mGLContextWindow, sdlApp->mGLContext); + } mSDLWindow = NULL; } @@ -418,6 +439,7 @@ SdlBFApp::SdlBFApp() BF_GET_SDLPROC(SDL_memcpy); BF_GET_SDLPROC(SDL_CreateProperties); + BF_GET_SDLPROC(SDL_DestroyProperties); BF_GET_SDLPROC(SDL_SetNumberProperty); BF_GET_SDLPROC(SDL_SetBooleanProperty); BF_GET_SDLPROC(SDL_SetStringProperty); @@ -426,8 +448,10 @@ SdlBFApp::SdlBFApp() BF_GET_SDLPROC(SDL_CreateWindowWithProperties); BF_GET_SDLPROC(SDL_GetWindowID); BF_GET_SDLPROC(SDL_DestroyWindow); + BF_GET_SDLPROC(SDL_SyncWindow); BF_GET_SDLPROC(SDL_GetWindowPosition); BF_GET_SDLPROC(SDL_SetWindowPosition); + BF_GET_SDLPROC(SDL_GetWindowSizeInPixels); BF_GET_SDLPROC(SDL_GetWindowSize); BF_GET_SDLPROC(SDL_SetWindowSize); BF_GET_SDLPROC(SDL_SetWindowMinimumSize); @@ -459,10 +483,14 @@ SdlBFApp::SdlBFApp() BF_GET_SDLPROC(SDL_GetDisplayBounds); BF_GET_SDLPROC(SDL_GetDesktopDisplayMode); BF_GET_SDLPROC(SDL_HasRectIntersection); + BF_GET_SDLPROC(SDL_GetDisplayForWindow); + BF_GET_SDLPROC(SDL_GetCurrentDisplayMode); BF_GET_SDLPROC(SDL_CreateSurfaceFrom); BF_GET_SDLPROC(SDL_GL_CreateContext); + BF_GET_SDLPROC(SDL_GL_GetCurrentContext); + BF_GET_SDLPROC(SDL_GL_GetCurrentWindow); BF_GET_SDLPROC(SDL_GL_MakeCurrent); BF_GET_SDLPROC(SDL_GL_SetAttribute); BF_GET_SDLPROC(SDL_GL_GetProcAddress); @@ -471,12 +499,21 @@ SdlBFApp::SdlBFApp() BF_GET_SDLPROC(SDL_GetDefaultCursor); BF_GET_SDLPROC(SDL_CreateSystemCursor); BF_GET_SDLPROC(SDL_SetCursor); + BF_GET_SDLPROC(SDL_GetWindowFlags); + BF_GET_SDLPROC(SDL_HideWindow); + BF_GET_SDLPROC(SDL_RestoreWindow); + BF_GET_SDLPROC(SDL_MinimizeWindow); + BF_GET_SDLPROC(SDL_MaximizeWindow); + BF_GET_SDLPROC(SDL_ShowWindow); + BF_GET_SDLPROC(SDL_RaiseWindow); } mDataDir = mInstallDir; if (bf_SDL_Init(SDL_INIT_VIDEO | SDL_INIT_GAMEPAD) < 0) BF_FATAL(StrFormat("Unable to initialize SDL: %s", bf_SDL_GetError()).c_str()); + + bf_SDL_SetHint(SDL_HINT_MOUSE_FOCUS_CLICKTHROUGH, "1"); } SdlBFApp::~SdlBFApp() @@ -491,174 +528,177 @@ SdlBFWindow* SdlBFApp::GetSdlWindowFromId(uint32 id) return window; } -void SdlBFApp::Init() -{ - mRunning = true; - mInMsgProc = false; - -// bf_SDL_SetHint(SDL_HINT_EVENT_LOGGING, "1"); - - mRenderDevice = new GLRenderDevice(); - mRenderDevice->Init(this); -} - -void SdlBFApp::Run() +void SdlBFApp::ProcessSDLEvents() { - while (mRunning) + SDL_Event sdlEvent; + while (bf_SDL_PollEvent(&sdlEvent)) { - SDL_Event sdlEvent; - while (true) + switch (sdlEvent.type) { - { - //Beefy::DebugTimeGuard suspendTimeGuard(30, "BFApp::Run1"); - if (!bf_SDL_PollEvent(&sdlEvent)) - break; - } - - //Beefy::DebugTimeGuard suspendTimeGuard(30, "BFApp::Run2"); - - switch (sdlEvent.type) + case SDL_EVENT_WINDOW_CLOSE_REQUESTED: { - case SDL_EVENT_WINDOW_CLOSE_REQUESTED: - { - SdlBFWindow* sdlBFWindow = GetSdlWindowFromId(sdlEvent.window.windowID); - if(sdlBFWindow != NULL) - if (sdlBFWindow->mCloseQueryFunc(sdlBFWindow) != 0) - gBFApp->RemoveWindow(sdlBFWindow); - } - break; - case SDL_EVENT_WINDOW_FOCUS_GAINED: - { - SdlBFWindow* sdlBFWindow = GetSdlWindowFromId(sdlEvent.window.windowID); - if(sdlBFWindow != NULL) - sdlBFWindow->mGotFocusFunc(sdlBFWindow); - } - break; - case SDL_EVENT_WINDOW_FOCUS_LOST: - { - SdlBFWindow* sdlBFWindow = GetSdlWindowFromId(sdlEvent.window.windowID); - if(sdlBFWindow != NULL) - { - sdlBFWindow->mLostFocusFunc(sdlBFWindow); - mIsControlDown = false; - } - } - break; - case SDL_EVENT_MOUSE_BUTTON_UP: - { - SdlBFWindow* sdlBFWindow = GetSdlWindowFromId(sdlEvent.button.windowID); - if (sdlBFWindow != NULL) - sdlBFWindow->mMouseUpFunc(sdlBFWindow, sdlEvent.button.x, sdlEvent.button.y, bfMouseBtnOf[sdlEvent.button.button]); - } - break; - case SDL_EVENT_MOUSE_BUTTON_DOWN: - { - SdlBFWindow* sdlBFWindow = GetSdlWindowFromId(sdlEvent.button.windowID); - if (sdlBFWindow != NULL) - sdlBFWindow->mMouseDownFunc(sdlBFWindow, sdlEvent.button.x, sdlEvent.button.y, bfMouseBtnOf[sdlEvent.button.button], sdlEvent.button.clicks); - } - break; - case SDL_EVENT_MOUSE_MOTION: - { - SdlBFWindow* sdlBFWindow = GetSdlWindowFromId(sdlEvent.button.windowID); - if (sdlBFWindow != NULL) - sdlBFWindow->mMouseMoveFunc(sdlBFWindow, sdlEvent.button.x, sdlEvent.button.y); - } - break; - case SDL_EVENT_MOUSE_WHEEL: - { - uint ucNumLines = 3; // Default - SdlBFWindow* sdlBFWindow = GetSdlWindowFromId(sdlEvent.wheel.windowID); - if(sdlBFWindow != NULL) - sdlBFWindow->mMouseWheelFunc(sdlBFWindow, sdlEvent.wheel.mouse_x, sdlEvent.wheel.mouse_y, sdlEvent.wheel.x, sdlEvent.wheel.y * (float)ucNumLines); - } - break; - case SDL_EVENT_WINDOW_MOUSE_ENTER: - { - SdlBFWindow* sdlBFWindow = GetSdlWindowFromId(sdlEvent.window.windowID); - if(sdlBFWindow != NULL) - RefreshMouseVisibility(sdlBFWindow); - } - break; - case SDL_EVENT_WINDOW_DESTROYED: + SdlBFWindow* sdlBFWindow = GetSdlWindowFromId(sdlEvent.window.windowID); + if(sdlBFWindow != NULL) + if (sdlBFWindow->mCloseQueryFunc(sdlBFWindow) != 0) + gBFApp->RemoveWindow(sdlBFWindow); + } + break; + case SDL_EVENT_WINDOW_FOCUS_GAINED: + { + SdlBFWindow* sdlBFWindow = GetSdlWindowFromId(sdlEvent.window.windowID); + if(sdlBFWindow != NULL) + sdlBFWindow->mGotFocusFunc(sdlBFWindow); + } + break; + case SDL_EVENT_WINDOW_FOCUS_LOST: + { + SdlBFWindow* sdlBFWindow = GetSdlWindowFromId(sdlEvent.window.windowID); + if(sdlBFWindow != NULL) { - SdlBFWindow* sdlBFWindow = GetSdlWindowFromId(bf_SDL_GetWindowID(bf_SDL_GetMouseFocus())); - if(sdlBFWindow != NULL) - RefreshMouseVisibility(sdlBFWindow); + sdlBFWindow->mLostFocusFunc(sdlBFWindow); + mIsControlDown = false; } - break; - case SDL_EVENT_KEY_DOWN: + } + break; + case SDL_EVENT_MOUSE_BUTTON_UP: + { + SdlBFWindow* sdlBFWindow = GetSdlWindowFromId(sdlEvent.button.windowID); + if (sdlBFWindow != NULL) + sdlBFWindow->mMouseUpFunc(sdlBFWindow, sdlEvent.button.x, sdlEvent.button.y, bfMouseBtnOf[sdlEvent.button.button]); + } + break; + case SDL_EVENT_MOUSE_BUTTON_DOWN: + { + SdlBFWindow* sdlBFWindow = GetSdlWindowFromId(sdlEvent.button.windowID); + if (sdlBFWindow != NULL) + sdlBFWindow->mMouseDownFunc(sdlBFWindow, sdlEvent.button.x, sdlEvent.button.y, bfMouseBtnOf[sdlEvent.button.button], sdlEvent.button.clicks); + } + break; + case SDL_EVENT_MOUSE_MOTION: + { + SdlBFWindow* sdlBFWindow = GetSdlWindowFromId(sdlEvent.button.windowID); + if (sdlBFWindow != NULL) + sdlBFWindow->mMouseMoveFunc(sdlBFWindow, sdlEvent.button.x, sdlEvent.button.y); + } + break; + case SDL_EVENT_MOUSE_WHEEL: + { + uint ucNumLines = 3; // Default + SdlBFWindow* sdlBFWindow = GetSdlWindowFromId(sdlEvent.wheel.windowID); + if(sdlBFWindow != NULL) + sdlBFWindow->mMouseWheelFunc(sdlBFWindow, sdlEvent.wheel.mouse_x, sdlEvent.wheel.mouse_y, sdlEvent.wheel.x, sdlEvent.wheel.y * (float)ucNumLines); + } + break; + case SDL_EVENT_WINDOW_MOUSE_ENTER: + { + SdlBFWindow* sdlBFWindow = GetSdlWindowFromId(sdlEvent.window.windowID); + if(sdlBFWindow != NULL) + RefreshMouseVisibility(sdlBFWindow); + } + break; + case SDL_EVENT_WINDOW_DESTROYED: + { + SdlBFWindow* sdlBFWindow = GetSdlWindowFromId(bf_SDL_GetWindowID(bf_SDL_GetMouseFocus())); + if(sdlBFWindow != NULL) + RefreshMouseVisibility(sdlBFWindow); + } + break; + case SDL_EVENT_KEY_DOWN: + { + SdlBFWindow* sdlBFWindow = GetSdlWindowFromId(sdlEvent.key.windowID); + if (sdlBFWindow != NULL) { - SdlBFWindow* sdlBFWindow = GetSdlWindowFromId(sdlEvent.key.windowID); - if (sdlBFWindow != NULL) + sdlBFWindow->mKeyDownFunc(sdlBFWindow, SDLConvertKeyCode(sdlEvent.key.key), sdlEvent.key.repeat); + switch (sdlEvent.key.key) // These keys are not handled by SDL_TEXTINPUT { - sdlBFWindow->mKeyDownFunc(sdlBFWindow, SDLConvertKeyCode(sdlEvent.key.key), sdlEvent.key.repeat); - switch (sdlEvent.key.key) // These keys are not handled by SDL_TEXTINPUT - { - case SDLK_RETURN: - sdlBFWindow->mKeyCharFunc(sdlBFWindow, '\n'); - break; - case SDLK_BACKSPACE: - sdlBFWindow->mKeyCharFunc(sdlBFWindow, mIsControlDown ? '\x7F' : '\b'); - break; - case SDLK_TAB: - sdlBFWindow->mKeyCharFunc(sdlBFWindow, '\t'); - break; - case SDLK_LCTRL: - mIsControlDown = true; - break; - - default:; - } + case SDLK_RETURN: + sdlBFWindow->mKeyCharFunc(sdlBFWindow, '\n'); + break; + case SDLK_BACKSPACE: + sdlBFWindow->mKeyCharFunc(sdlBFWindow, mIsControlDown ? '\x7F' : '\b'); + break; + case SDLK_TAB: + sdlBFWindow->mKeyCharFunc(sdlBFWindow, '\t'); + break; + case SDLK_LCTRL: + mIsControlDown = true; + break; + + default:; } } - break; - case SDL_EVENT_TEXT_INPUT: + } + break; + case SDL_EVENT_TEXT_INPUT: + { + SdlBFWindow* sdlBFWindow = GetSdlWindowFromId(sdlEvent.text.windowID); + if (sdlBFWindow != NULL) { - SdlBFWindow* sdlBFWindow = GetSdlWindowFromId(sdlEvent.text.windowID); - if (sdlBFWindow != NULL) - { - const auto wideString = Beefy::UTF8Decode(sdlEvent.text.text); - for (int i = 0; i < wideString.length(); i++) - sdlBFWindow->mKeyCharFunc(sdlBFWindow, wideString[i]); - } + const auto wideString = Beefy::UTF8Decode(sdlEvent.text.text); + for (int i = 0; i < wideString.length(); i++) + sdlBFWindow->mKeyCharFunc(sdlBFWindow, wideString[i]); } - break; - case SDL_EVENT_KEY_UP: - { - SdlBFWindow* sdlBFWindow = GetSdlWindowFromId(sdlEvent.key.windowID); - if (sdlBFWindow != NULL) - sdlBFWindow->mKeyUpFunc(sdlBFWindow, SDLConvertKeyCode(sdlEvent.key.key)); + } + break; + case SDL_EVENT_KEY_UP: + { + SdlBFWindow* sdlBFWindow = GetSdlWindowFromId(sdlEvent.key.windowID); + if (sdlBFWindow != NULL) + sdlBFWindow->mKeyUpFunc(sdlBFWindow, SDLConvertKeyCode(sdlEvent.key.key)); - if (sdlEvent.key.key == SDLK_LCTRL) - mIsControlDown = false; - } - break; - case SDL_EVENT_WINDOW_MOVED: -// case SDL_EVENT_WINDOW_RESIZED: - case SDL_EVENT_WINDOW_PIXEL_SIZE_CHANGED: + if (sdlEvent.key.key == SDLK_LCTRL) + mIsControlDown = false; + } + break; + case SDL_EVENT_WINDOW_MOVED: + case SDL_EVENT_WINDOW_RESIZED: + { + SdlBFWindow* sdlBFWindow = GetSdlWindowFromId(sdlEvent.window.windowID); + if (sdlBFWindow != NULL) { - SdlBFWindow* sdlBFWindow = GetSdlWindowFromId(sdlEvent.window.windowID); - if (sdlBFWindow != NULL) - { - if (sdlBFWindow->mHasPositionInit) - { - if (sdlEvent.type == SDL_EVENT_WINDOW_PIXEL_SIZE_CHANGED) - { - sdlBFWindow->mRenderWindow->Resized(); - } - sdlBFWindow->mMovedFunc(sdlBFWindow); - } - else - { - sdlBFWindow->mHasPositionInit = true; - } - } + sdlBFWindow->mMovedFunc(sdlBFWindow); + + // if (sdlBFWindow->mHasPositionInit) + // { + // if (sdlEvent.type == SDL_EVENT_WINDOW_PIXEL_SIZE_CHANGED) + // sdlBFWindow->mRenderWindow->Resized(); + // + // + // } + // else + // { + // sdlBFWindow->mHasPositionInit = true; + // } } - break; } + break; + case SDL_EVENT_WINDOW_PIXEL_SIZE_CHANGED: + { + SdlBFWindow* sdlBFWindow = GetSdlWindowFromId(sdlEvent.window.windowID); + if (sdlBFWindow != NULL) + sdlBFWindow->mRenderWindow->Resized(); + } + break; } + } +} +void SdlBFApp::Init() +{ + mRunning = true; + mInMsgProc = false; + +// bf_SDL_SetHint(SDL_HINT_EVENT_LOGGING, "1"); + + mRenderDevice = new GLRenderDevice(); + mRenderDevice->Init(this); +} + +void SdlBFApp::Run() +{ + while (mRunning) + { + ProcessSDLEvents(); Process(); } } @@ -670,12 +710,6 @@ void SdlBFApp::Draw() { //Beefy::DebugTimeGuard suspendTimeGuard(30, "SdlBFApp::Draw"); - glDisable(GL_SCISSOR_TEST); - glDisable(GL_CULL_FACE); - glDisable(GL_DEPTH_TEST); - glClearColor(0.0f, 0.0f, 0.0f, 0.0f); - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - gPixelsDrawn = 0; gBFDrawBatchCount = 0; @@ -705,10 +739,7 @@ void SdlBFWindow::GetPosition(int* x, int* y, int* width, int* height, int* clie *clientX = *x; if (clientY) *clientY = *y; - if (clientWidth) - *clientWidth = *width; - if (clientHeight) - *clientHeight = *height; + bf_SDL_GetWindowSizeInPixels(mSDLWindow, clientWidth, clientHeight); } void SdlBFApp::PhysSetCursor() @@ -741,13 +772,31 @@ void SdlBFWindow::SetClientPosition(int x, int y) void SdlBFWindow::Resize(int x, int y, int width, int height, ShowKind showKind) { bf_SDL_SetWindowPosition(mSDLWindow, x, y); + bf_SDL_SyncWindow(mSDLWindow); bf_SDL_SetWindowSize(mSDLWindow, width, height); + bf_SDL_SyncWindow(mSDLWindow); + Show(showKind); + bf_SDL_SyncWindow(mSDLWindow); + + if (mRenderWindow != NULL) + mRenderWindow->Resized(); + if (mMovedFunc != NULL) + mMovedFunc(this); } void SdlBFWindow::GetPlacement(int* normX, int* normY, int* normWidth, int* normHeight, int* showKind) { bf_SDL_GetWindowPosition(mSDLWindow, normX, normY); bf_SDL_GetWindowSize(mSDLWindow, normWidth, normHeight); + SDL_WindowFlags flags = bf_SDL_GetWindowFlags(mSDLWindow); + if ((flags & SDL_WINDOW_HIDDEN) == SDL_WINDOW_HIDDEN) + *showKind = ShowKind_Hide; + else if ((flags & SDL_WINDOW_MAXIMIZED) == SDL_WINDOW_MAXIMIZED) + *showKind = ShowKind_ShowMaximized; + else if ((flags & SDL_WINDOW_MINIMIZED) == SDL_WINDOW_MINIMIZED) + *showKind = ShowKind_ShowMinimized; + else + *showKind = ShowKind_ShowNormal; } void SdlBFWindow::SetAlpha(float alpha, uint32 destAlphaSrcMask, bool isMouseVisible) @@ -840,6 +889,45 @@ void SdlBFWindow::ModalsRemoved() //::SetFocus(mHWnd); } +void SdlBFWindow::Show(ShowKind showKind) +{ + switch (showKind) + { + case BFWindow::ShowKind_Hide: + bf_SDL_HideWindow(mSDLWindow); + break; + case BFWindow::ShowKind_Normal: + bf_SDL_RestoreWindow(mSDLWindow); + break; + case BFWindow::ShowKind_Minimized: + bf_SDL_MinimizeWindow(mSDLWindow); + break; + case BFWindow::ShowKind_Maximized: + bf_SDL_MaximizeWindow(mSDLWindow); + break; + case BFWindow::ShowKind_Show: + bf_SDL_ShowWindow(mSDLWindow); + break; + case BFWindow::ShowKind_ShowNormal: + bf_SDL_RestoreWindow(mSDLWindow); + bf_SDL_ShowWindow(mSDLWindow); + break; + case BFWindow::ShowKind_ShowMinimized: + bf_SDL_MinimizeWindow(mSDLWindow); + bf_SDL_ShowWindow(mSDLWindow); + break; + case BFWindow::ShowKind_ShowMaximized: + bf_SDL_MaximizeWindow(mSDLWindow); + bf_SDL_ShowWindow(mSDLWindow); + break; + } +} + +void SdlBFWindow::SetForeground() +{ + bf_SDL_RaiseWindow(mSDLWindow); +} + void SdlBFWindow::SetTitle(const char* title) { bf_SDL_SetWindowTitle(mSDLWindow, title); diff --git a/BeefySysLib/platform/sdl/SdlBFApp.h b/BeefySysLib/platform/sdl/SdlBFApp.h index 94611e889..106856d90 100644 --- a/BeefySysLib/platform/sdl/SdlBFApp.h +++ b/BeefySysLib/platform/sdl/SdlBFApp.h @@ -46,8 +46,8 @@ class SdlBFWindow : public BFWindow virtual void ModalsRemoved() override; - virtual void Show(ShowKind showKind) {} - virtual void SetForeground() override {}; + virtual void Show(ShowKind showKind) override; + virtual void SetForeground() override; }; typedef Dictionary SdlWindowMap; @@ -61,7 +61,7 @@ class SdlBFApp : public BFApp SdlWindowMap mSdlWindowMap; SdlClipboardData* mSdlClipboardData; SDL_GLContext mGLContext; - + SDL_Window* mGLContextWindow; protected: virtual void Draw() override; @@ -69,6 +69,7 @@ class SdlBFApp : public BFApp const char* GetClipboardFormat(const StringImpl& format); SdlBFWindow* GetSdlWindowFromId(uint32 id); + void ProcessSDLEvents(); public: SdlBFApp(); diff --git a/IDE/src/ui/AutoComplete.bf b/IDE/src/ui/AutoComplete.bf index c14774763..5ce070a9b 100644 --- a/IDE/src/ui/AutoComplete.bf +++ b/IDE/src/ui/AutoComplete.bf @@ -288,7 +288,7 @@ namespace IDE.ui return; } - if ((mWidgetWindow != null) && (!mWidgetWindow.mHasClosed) && (mWidgetWindow.HasParent(window))) + if ((mAutoComplete.mIgnoreMove == 0) && (mWidgetWindow != null) && (!mWidgetWindow.mHasClosed) && (mWidgetWindow.HasParent(window))) mAutoComplete.Close(); } @@ -381,7 +381,6 @@ namespace IDE.ui using (g.PushColor(0xFFFFFFFF)) g.DrawBox(DarkTheme.sDarkTheme.GetImage(DarkTheme.ImageIdx.Menu), 0, 0, boxWidth - GS!(6), drawHeight - GS!(8)); } - g.SetFont(IDEApp.sApp.mCodeFont); /*using (g.PushColor(0x80FF0000)) @@ -645,9 +644,11 @@ namespace IDE.ui int windowHeight = (int)(mWantHeight + Math.Max(0, mDocHeight - GS!(32))); + mAutoComplete.mIgnoreMove++; mWidgetWindow.Resize(mWidgetWindow.mNormX, mWidgetWindow.mNormY, windowWidth, windowHeight); mScrollContent.mWidth = mWidth; //Resize(0, 0, mWidgetWindow.mClientWidth, mWidgetWindow.mClientHeight); + mAutoComplete.mIgnoreMove--; ResizeContent(-1, -1, mVertScrollbar != null); } } @@ -995,7 +996,9 @@ namespace IDE.ui { if (mOwnsWindow) { + mAutoComplete.mIgnoreMove++; mAutoComplete.UpdateWindow(ref mWidgetWindow, this, mAutoComplete.mInvokeSrcPositions[0], (int32)extWidth, (int32)extHeight); + mAutoComplete.mIgnoreMove--; } else { @@ -1391,6 +1394,7 @@ namespace IDE.ui public bool mIsDocumentationPass; public bool mIsUserRequested; + public int mIgnoreMove; bool mClosed; bool mPopulating; float mWantX; @@ -1553,6 +1557,8 @@ namespace IDE.ui public void Update() { + Debug.Assert((mIgnoreMove >= 0) && (mIgnoreMove <= 4)); + if ((mInvokeWindow != null) && (!mInvokeWidget.mIsAboveText)) { int textIdx = mTargetEditWidget.Content.mTextCursors.Front.mCursorTextPos; @@ -1581,11 +1587,13 @@ namespace IDE.ui int insertLine = line; if ((insertLine != invokeLine) && ((insertLine - invokeLine) * gApp.mCodeFont.GetHeight() < GS!(40))) { + mIgnoreMove++; mInvokeWidget.mIsAboveText = true; mInvokeWidget.ResizeContent(false); UpdateWindow(ref mInvokeWindow, mInvokeWidget, mInvokeSrcPositions[0], (int32)mInvokeWidget.mWidth, (int32)mInvokeWidget.mHeight); if (mListWindow != null) UpdateWindow(ref mListWindow, mAutoCompleteListWidget, mInsertStartIdx.Value, mListWindow.mWindowWidth, mListWindow.mWindowHeight); + mIgnoreMove--; } } @@ -1906,6 +1914,11 @@ namespace IDE.ui return hadMatch; } + public void SetIgnoreMove(bool ignoreMove) + { + mIgnoreMove += ignoreMove ? 1 : -1; + } + // IDEHelper/third_party/FtsFuzzyMatch.h [CallingConvention(.Stdcall), CLink] static extern bool fts_fuzzy_match(char8* pattern, char8* str, ref int32 outScore, uint8* matches, int maxMatches); @@ -2038,7 +2051,7 @@ namespace IDE.ui if (changedAfterInfo) { mAutoCompleteListWidget.mSelectIdx = -1; - + if ((curString.Length == 0) && (!mIsMember) && (mInvokeSrcPositions == null)) { mPopulating = false; @@ -2143,6 +2156,8 @@ namespace IDE.ui SelectEntry(""); } + SetIgnoreMove(true); + gApp.mAutoCompletePanel.StartBind(this); int32 prevInvokeSelect = 0; @@ -2184,6 +2199,7 @@ namespace IDE.ui HandleAutoCompleteListWidget(visibleCount); } gApp.mAutoCompletePanel.FinishBind(); + SetIgnoreMove(false); if ((mAutoCompleteListWidget != null) && (!mAutoCompleteListWidget.mIsInitted)) mAutoCompleteListWidget.Init(); @@ -2390,6 +2406,7 @@ namespace IDE.ui { if (mAutoCompleteListWidget != null) { + mIgnoreMove++; if (IsInPanel()) { mAutoCompleteListWidget.RemoveSelf(); @@ -2403,6 +2420,7 @@ namespace IDE.ui else delete mAutoCompleteListWidget; mAutoCompleteListWidget = null; + mIgnoreMove--; } } if (mAutoCompleteListWidget == null) diff --git a/IDEHelper/CMakeLists.txt b/IDEHelper/CMakeLists.txt index e5e41fbd8..cb264cfd7 100644 --- a/IDEHelper/CMakeLists.txt +++ b/IDEHelper/CMakeLists.txt @@ -194,7 +194,6 @@ if (HAVE_BACKTRACE_HEADERS) endif() if (DEFINED BF_ENABLE_SDL) - string(APPEND TARGET_LIBS_OS " -lGL") string(STRIP ${TARGET_LIBS_OS} TARGET_LIBS_OS) endif() diff --git a/bin/build.sh b/bin/build.sh index 1faff2bb1..bb6191150 100755 --- a/bin/build.sh +++ b/bin/build.sh @@ -19,7 +19,6 @@ do if [[ $i == "sdl" ]]; then echo "Using SDL" USE_SDL="-DBF_ENABLE_SDL=1" - SDL_LINKOPTS="-lGL" fi if [[ $i == "no_ffi" ]]; then @@ -147,7 +146,7 @@ ln -s -f $ROOTPATH/jbuild/Release/bin/libIDEHelper.a ../../BeefLibs/Beefy2D/dist ### DEBUG ### echo Building BeefBuild_bootd -../../jbuild_d/Debug/bin/BeefBoot --out="BeefBuild_bootd" --src=../src --src=../../BeefBuild/src --src=../../BeefLibs/corlib/src --src=../../BeefLibs/Beefy2D/src --define=CLI --define=DEBUG --startup=BeefBuild.Program --linkparams="./libBeefRT_d.a ./libIDEHelper_d.a ./libBeefySysLib_d.a ./libhunspell.$LIBEXT $(< ../../IDE/dist/IDEHelper_libs_d.txt) $SDL_LINKOPTS $LINKOPTS" +../../jbuild_d/Debug/bin/BeefBoot --out="BeefBuild_bootd" --src=../src --src=../../BeefBuild/src --src=../../BeefLibs/corlib/src --src=../../BeefLibs/Beefy2D/src --define=CLI --define=DEBUG --startup=BeefBuild.Program --linkparams="./libBeefRT_d.a ./libIDEHelper_d.a ./libBeefySysLib_d.a ./libhunspell.$LIBEXT $(< ../../IDE/dist/IDEHelper_libs_d.txt) $LINKOPTS" echo Building BeefBuild_d ./BeefBuild_bootd -clean -proddir=../../BeefBuild -config=Debug echo Testing IDEHelper/Tests in BeefBuild_d @@ -156,7 +155,7 @@ echo Testing IDEHelper/Tests in BeefBuild_d ### RELEASE ### echo Building BeefBuild_boot -../../jbuild/Release/bin/BeefBoot --out="BeefBuild_boot" --src=../src --src=../../BeefBuild/src --src=../../BeefLibs/corlib/src --src=../../BeefLibs/Beefy2D/src --define=CLI --startup=BeefBuild.Program --linkparams="./libBeefRT.a ./libIDEHelper.a ./libBeefySysLib.a ./libhunspell.$LIBEXT $(< ../../IDE/dist/IDEHelper_libs.txt) $SDL_LINKOPTS $LINKOPTS" +../../jbuild/Release/bin/BeefBoot --out="BeefBuild_boot" --src=../src --src=../../BeefBuild/src --src=../../BeefLibs/corlib/src --src=../../BeefLibs/Beefy2D/src --define=CLI --startup=BeefBuild.Program --linkparams="./libBeefRT.a ./libIDEHelper.a ./libBeefySysLib.a ./libhunspell.$LIBEXT $(< ../../IDE/dist/IDEHelper_libs.txt) $LINKOPTS" echo Building BeefBuild ./BeefBuild_boot -clean -proddir=../../BeefBuild -config=Release echo Testing IDEHelper/Tests in BeefBuild