//========================================================= // loadtexture // - load a texture based on glaux load bitmap //--------------------------------------------------------- void LoadTexture(char *filename) { AUX_RGBImageRec *textureimage[1]; // create space for texture memset(textureimage, 0, sizeof(void *)*1); // set ptr to NULL // load the bitmap, from the file if (textureimage[0] = LoadBitmap(filename)) { // Bind the texture glBindTexture(GL_TEXTURE_2D, GetTexture(textureindex)); glTexImage2D(GL_TEXTURE_2D, 0, 3, textureimage[0]->sizeX, textureimage[0]->sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE, textureimage[0]->data); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); } // end of the if if (textureimage[0]) { if (textureimage[0]->data) { free(textureimage[0]->data); // free up the allocated memory } // end of the if free(textureimage[0]); // free the entire struct } // end of the if NextTexture(); } // end of the function
void FGLRenderBuffers::RenderEffect(const FString &name) { if (hw_postprocess.Effects[name].Size() == 0) return; FGLDebug::PushGroup(name.GetChars()); FGLPostProcessState savedState; for (const PPStep &step : hw_postprocess.Effects[name]) { // Bind input textures for (unsigned int index = 0; index < step.Textures.Size(); index++) { savedState.SaveTextureBindings(index + 1); const PPTextureInput &input = step.Textures[index]; int filter = (input.Filter == PPFilterMode::Nearest) ? GL_NEAREST : GL_LINEAR; int wrap = (input.Wrap == PPWrapMode::Clamp) ? GL_CLAMP : GL_REPEAT; switch (input.Type) { default: case PPTextureType::CurrentPipelineTexture: BindCurrentTexture(index, filter, wrap); break; case PPTextureType::NextPipelineTexture: I_FatalError("PPTextureType::NextPipelineTexture not allowed as input\n"); break; case PPTextureType::PPTexture: GLTextures[input.Texture].Bind(index, filter, wrap); break; case PPTextureType::SceneColor: BindSceneColorTexture(index); break; case PPTextureType::SceneFog: BindSceneFogTexture(index); break; case PPTextureType::SceneNormal: BindSceneNormalTexture(index); break; case PPTextureType::SceneDepth: BindSceneDepthTexture(index); break; } } // Set render target switch (step.Output.Type) { default: I_FatalError("Unsupported postprocess output type\n"); break; case PPTextureType::CurrentPipelineTexture: BindCurrentFB(); break; case PPTextureType::NextPipelineTexture: BindNextFB(); break; case PPTextureType::PPTexture: if (GLTextureFBs[step.Output.Texture]) GLTextureFBs[step.Output.Texture].Bind(); else GLTextureFBs[step.Output.Texture] = CreateFrameBuffer(step.Output.Texture.GetChars(), GLTextures[step.Output.Texture]); break; case PPTextureType::SceneColor: BindSceneFB(false); break; } // Set blend mode if (step.BlendMode.BlendOp == STYLEOP_Add && step.BlendMode.SrcAlpha == STYLEALPHA_One && step.BlendMode.DestAlpha == STYLEALPHA_Zero && step.BlendMode.Flags == 0) { glDisable(GL_BLEND); } else { // To do: support all the modes glEnable(GL_BLEND); glBlendEquation(GL_FUNC_ADD); if (step.BlendMode.SrcAlpha == STYLEALPHA_One && step.BlendMode.DestAlpha == STYLEALPHA_One) glBlendFunc(GL_ONE, GL_ONE); else glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); } // Setup viewport glViewport(step.Viewport.left, step.Viewport.top, step.Viewport.width, step.Viewport.height); auto &shader = GLShaders[step.ShaderName]; // Set uniforms if (step.Uniforms.Data.Size() > 0) { if (!shader->Uniforms) shader->Uniforms.reset(screen->CreateDataBuffer(POSTPROCESS_BINDINGPOINT, false)); shader->Uniforms->SetData(step.Uniforms.Data.Size(), step.Uniforms.Data.Data()); shader->Uniforms->BindBase(); } // Set shader shader->Bind(NOQUEUE); // Draw the screen quad GLRenderer->RenderScreenQuad(); // Advance to next PP texture if our output was sent there if (step.Output.Type == PPTextureType::NextPipelineTexture) NextTexture(); } glViewport(screen->mScreenViewport.left, screen->mScreenViewport.top, screen->mScreenViewport.width, screen->mScreenViewport.height); FGLDebug::PopGroup(); }