diff --git a/code/CMakeLists.txt b/code/CMakeLists.txt index d318cb8..c171a81 100644 --- a/code/CMakeLists.txt +++ b/code/CMakeLists.txt @@ -631,7 +631,10 @@ set(src_redalert ./redalert/mapscript.cpp ./redalert/txtprnt.cpp ./redalert/tilesetxml.cpp - "redalert/sidebareditor.cpp" "redalert/light.cpp") + "redalert/sidebareditor.cpp" + "redalert/rendertexture.cpp" + "redalert/rendertexture.h" + "redalert/light.cpp") set(src_external #glew diff --git a/code/redalert/function.h b/code/redalert/function.h index 3952823..2cf325d 100644 --- a/code/redalert/function.h +++ b/code/redalert/function.h @@ -235,6 +235,7 @@ struct NoInitClass { #include "shastraw.h" #include "rndstraw.h" #include "light.h" +#include "rendertexture.h" // Should be part of WWLIB.H. This is used in JSHELL.CPP. typedef struct { diff --git a/code/redalert/light.cpp b/code/redalert/light.cpp index 2f81c18..42fd4ea 100644 --- a/code/redalert/light.cpp +++ b/code/redalert/light.cpp @@ -29,15 +29,16 @@ LightManager::LightManager() { void LightManager::Init(void) { lightEditorIcon = Image_LoadImage("ui/edwin/lightbulb.png"); + pointLightAttenImage0 = Image_LoadImage("ui/lights/light_point_atten.png"); } void LightManager::RenderLights(void) { - for(int i = 0; i < MAX_WORLD_LIGHTS; i++) { + for (int i = 0; i < MAX_WORLD_LIGHTS; i++) { if (!lights[i].active) { continue; } - if(!lights[i].isPending) { + if (!lights[i].isPending) { int screenx, screeny; lights[i].GetRenderPosition(screenx, screeny); GL_RenderImage(lightEditorIcon, screenx, screeny, 30, 30); @@ -75,12 +76,12 @@ Light_t *LightManager::PlaceLight(char *name, int x, int y, float r, float g, fl else { strcpy(light->name, name); } - light->position = XYP_Coord(x, y); light->color.x = r; light->color.y = g; light->color.z = b; light->radius = radius; light->type = type; + light->PlaceLight(x, y); return light; } diff --git a/code/redalert/light.h b/code/redalert/light.h index 2ebbc44..e8361b3 100644 --- a/code/redalert/light.h +++ b/code/redalert/light.h @@ -54,6 +54,7 @@ private: Light_t lights[MAX_WORLD_LIGHTS]; int numLights; Image_t* lightEditorIcon; + Image_t* pointLightAttenImage0; }; extern LightManager lightManager; \ No newline at end of file diff --git a/code/redalert/newblit.cpp b/code/redalert/newblit.cpp index 0adcb06..c48170f 100644 --- a/code/redalert/newblit.cpp +++ b/code/redalert/newblit.cpp @@ -11,6 +11,10 @@ extern uint8_t g_ColorXlat[16]; bool forceForgegroundRender = false; int32_t g_currentColor; +//void GL_SetRenderTarget(void *renderTarget) { +// //ImGui::GetBackgroundDrawList()->AddCallback() +//} + void GL_ForceForegroundRender(bool force) { forceForgegroundRender = force; } diff --git a/code/redalert/rendertexture.cpp b/code/redalert/rendertexture.cpp new file mode 100644 index 0000000..dd9f088 --- /dev/null +++ b/code/redalert/rendertexture.cpp @@ -0,0 +1,136 @@ +// RenderTexture.cpp +// + +#include "function.h" +#include "image.h" +#include "gl/glew.h" + +/* +======================== +RenderTexture::RenderTexture +======================== +*/ +RenderTexture::RenderTexture(Image_t *colorImage, Image_t *depthImage) { + deviceHandle = -1; + if (colorImage != nullptr) + { + AddRenderImage(colorImage); + } + this->depthImage = depthImage; +} + +/* +======================== +RenderTexture::~RenderTexture +======================== +*/ +RenderTexture::~RenderTexture() { + if (deviceHandle != -1) + { + glDeleteFramebuffers(1, &deviceHandle); + deviceHandle = -1; + } +} +/* +================ +RenderTexture::AddRenderImage +================ +*/ +void RenderTexture::AddRenderImage(Image_t *image) { + if (deviceHandle != -1) { + assert(!"RenderTexture::AddRenderImage: Can't add render image after FBO has been created!"); + } + + colorImages.push_back(image); +} + +/* +================ +RenderTexture::InitRenderTexture +================ +*/ +void RenderTexture::InitRenderTexture(void) { + glGenFramebuffers(1, &deviceHandle); + glBindFramebuffer(GL_FRAMEBUFFER, deviceHandle); + + for (int i = 0; i < colorImages.size(); i++) { + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + i, GL_TEXTURE_2D, colorImages[i]->HouseImages[0].image[0][0], 0); + } + + if (depthImage != nullptr) { + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, depthImage->HouseImages[0].image[0][0], 0); + } + + if (colorImages.size() > 0) + { + GLenum DrawBuffers[5] = { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1, GL_COLOR_ATTACHMENT2, GL_COLOR_ATTACHMENT3, GL_COLOR_ATTACHMENT4 }; + if (colorImages.size() >= 5) { + assert(!"InitRenderTextures: Too many render targets!"); + } + glDrawBuffers(colorImages.size(), &DrawBuffers[0]); + } + + + if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) { + assert(!"RenderTexture::InitRenderTexture: Failed to create rendertexture!"); + } + + glBindFramebuffer(GL_FRAMEBUFFER, 0); +} + +/* +================ +RenderTexture::MakeCurrent +================ +*/ +void RenderTexture::MakeCurrent(void) { + glBindFramebuffer(GL_FRAMEBUFFER, deviceHandle); +} + +/* +================ +RenderTexture::BindNull +================ +*/ +void RenderTexture::BindNull(void) { + glBindFramebuffer(GL_FRAMEBUFFER, 0); +} + +int RenderTexture::GetWidth() const { return (colorImages.size() > 0) ? colorImages[0]->renderwidth[0] : depthImage->renderwidth[0]; } +int RenderTexture::GetHeight() const { return (colorImages.size() > 0) ? colorImages[0]->renderheight[0] : depthImage->renderheight[0]; } + +/* +================ +RenderTexture::Resize +================ +*/ +void RenderTexture::Resize(int width, int height) { + //Image_t *target = nullptr; + // + //if (colorImages.Num() > 0) { + // target = colorImages[0]; + //} + //else { + // target = depthImage; + //} + // + //if (target->GetOpts().width == width && target->GetOpts().height == height) { + // return; + //} + // + //for(int i = 0; i < colorImages.Num(); i++) { + // colorImages[i]->Resize(width, height); + //} + // + //if (depthImage != nullptr) { + // depthImage->Resize(width, height); + //} + // + //if (deviceHandle != -1) + //{ + // glDeleteFramebuffers(1, &deviceHandle); + // deviceHandle = -1; + //} + // + //InitRenderTexture(); +} diff --git a/code/redalert/rendertexture.h b/code/redalert/rendertexture.h new file mode 100644 index 0000000..817cacc --- /dev/null +++ b/code/redalert/rendertexture.h @@ -0,0 +1,43 @@ +#ifndef __RENDERTEXTURE_H__ +#define __RENDERTEXTURE_H__ + +struct Image_t; + +/* +================================================================================================ + + Render Texture + +================================================================================================ +*/ + +class RenderTexture { +public: + RenderTexture(Image_t*colorImage, Image_t *depthImage); + ~RenderTexture(); + + int GetWidth() const; + int GetHeight() const; + + Image_t* GetColorImage(int idx) const { return colorImages[idx]; } + Image_t* GetDepthImage() const { return depthImage; } + + int GetNumColorImages() const { return colorImages.size(); } + + void Resize( int width, int height ); + + void MakeCurrent( void ); + static void BindNull(void); + + unsigned int GetDeviceHandle(void) { return deviceHandle; } + + void AddRenderImage(Image_t*image); + void InitRenderTexture(void); +private: + + std::vector colorImages; + Image_t * depthImage; + unsigned int deviceHandle; +}; + +#endif //!__RENDERTEXTURE_H__ diff --git a/ui/lights/light_point_atten.png b/ui/lights/light_point_atten.png new file mode 100644 index 0000000..af6a1a8 Binary files /dev/null and b/ui/lights/light_point_atten.png differ