scrollviewer content overflow flashing bug
how to fix it?
Re: scrollviewer content overflow flashing bug
This seems to be an integration issue on your side. Make sure the offscreen phase is rendered before binding the main framebuffer, just have a look at our IntegrationGLUT sample.
-
sfernandez
Site Admin
- Posts: 3093
- Joined:
Re: scrollviewer content overflow flashing bug
And also make sure you are using a render target with DepthStencil, because the ScrollViewer uses stencil when it needs to clip its contents to the visible viewport.
Re: scrollviewer content overflow flashing bug
And also make sure you are using a render target with DepthStencil, because the ScrollViewer uses stencil when it needs to clip its contents to the visible viewport.
Thank you for your answer, I've tried your methods, but it also didn't work.This seems to be an integration issue on your side. Make sure the offscreen phase is rendered before binding the main framebuffer, just have a look at our IntegrationGLUT sample.
But when I used the "LayeredUI" approach to load the xaml include scrollviewer, the bug didn't show up and it worked very well.
Re: scrollviewer content overflow flashing bug
Are you able to reproduce this problem in the IntegrationGLUT sample? If so, please let us know the patches we should apply to see this bug.
Re: scrollviewer content overflow flashing bug
I am very sorry, i can not draw a triangle before draw noesisgui in IntegrationGLUT sample,
so i can't reproduce the bug, draw a triangle too hard in glut, i tried 3 hours without success. :(
so i can't reproduce the bug, draw a triangle too hard in glut, i tried 3 hours without success. :(
Re: scrollviewer content overflow flashing bug
You just draw a triangle before draw noesisgui(xaml, scrollviewer with long textblock), the problem will be reproduce.Are you able to reproduce this problem in the IntegrationGLUT sample? If so, please let us know the patches we should apply to see this bug.
Re: scrollviewer content overflow flashing bug
This is the code:
Code: Select all
#define GLEW_STATIC
#include <GL/glew.h>
#include <GLFW/glfw3.h>
#include <NsGui/IView.h>
#include <NsGui/IRenderer.h>
#include <NsGui/TextBlock.h>
#include <NsGui/Storyboard.h>
#include <NsApp/ThemeProviders.h>
#include <NsGui/FontProperties.h>
#include <NsGui/Grid.h>
#include <NsGui/IntegrationAPI.h>
#include <NsRender/GLFactory.h>
#include <NsRender/GLRenderDeviceApi.h>
#include <NsGui/Uri.h>
#include <iostream>
#include <cstdio>
void cbFramebufferSize(GLFWwindow* window, int width, int height);
void processInput(GLFWwindow* window);
void myNoesisRender(unsigned int targetFbo);
void myNoesisInit();
void myCreateFramebuffer();
void mySetupGlfw();
void mySetupTriangle();
void myDrawTriangle(unsigned int targetFbo);
const unsigned int SCR_WIDTH = 800;
const unsigned int SCR_HEIGHT = 600;
static Noesis::IView* _view;
static GLFWwindow* pWindow;
unsigned int fbo;
unsigned int triangleVBO, triangleVAO;
unsigned int textColorBuffer;
int numFrames = 0;
float triangleVertices[] = {
-0.5f, -0.5f, 0.0f,
0.5f, -0.5f, 0.0f,
0.0f, 0.5f, 0.0f
};
int numTriangleVertices = 3;
const char* vertexShaderSource = "#version 330 core\n"
"layout (location = 0) in vec3 aPos;\n"
"void main()\n"
"{\n"
" gl_Position = vec4(aPos.x, aPos.y, aPos.z, 1.0);\n"
"}\0";
const char* fragmentShaderSource =
"#version 330 core\n"
"out vec4 FragColor;\n"
"void main()\n"
"{"
" FragColor = vec4(1.0f, 0.5f, 0.2f, 1.0f);"
"}\0";
unsigned int shaderProgram;
//====================================================================================
int main()
{
mySetupGlfw();
GLenum glew_err = glewInit();
if (glew_err != GLEW_OK)
{
throw std::runtime_error(std::string("Error initializing GLEW, error: ") + (const char*)glewGetErrorString(glew_err));
return 0;
}
glEnable(GL_STENCIL_TEST);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_BLEND);
//glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
unsigned int vertexShader;
vertexShader = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(vertexShader, 1, &vertexShaderSource, NULL);
glCompileShader(vertexShader);
unsigned int fragmentShader;
fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(fragmentShader, 1, &fragmentShaderSource, NULL);
glCompileShader(fragmentShader);
shaderProgram = glCreateProgram();
glAttachShader(shaderProgram, vertexShader);
glAttachShader(shaderProgram, fragmentShader);
glLinkProgram(shaderProgram);
glDeleteShader(vertexShader);
glDeleteShader(fragmentShader);
mySetupTriangle();
myCreateFramebuffer();
myNoesisInit();
while (!glfwWindowShouldClose(pWindow)) {
processInput(pWindow);
myDrawTriangle(0);
myNoesisRender(fbo);
// Done drawing
glfwSwapBuffers(pWindow);
glfwPollEvents();
}
_view->GetRenderer()->Shutdown();
_view->Release();
glfwTerminate();
return 0;
}
//----------------------------------------------------------------------------------------
void myNoesisRender(unsigned int targetFramebuffer)
{
glBindFramebuffer(GL_FRAMEBUFFER, targetFramebuffer);
int w, h;
glfwGetFramebufferSize(pWindow, &w, &h);
glViewport(0, 0, w, h);
glClearColor(0.3f, 0.3f, 0.0f, 0.0f);
glClearStencil(0);
glClear(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// Update view (layout, animations, ...)
_view->Update(glfwGetTimerValue() / 1000.0f);
// Offscreen rendering phase populates textures needed by the on-screen rendering
_view->GetRenderer()->UpdateRenderTree();
_view->GetRenderer()->RenderOffscreen();
// If you are going to render here with your own engine you need to restore the GPU state
// because noesis changes it. In this case only framebuffer and viewport need to be restored
glBindFramebuffer(GL_FRAMEBUFFER, 0);
// Rendering is done in the active framebuffer
_view->GetRenderer()->Render();
}
//--------------------------------------------------------------------------------------
void myNoesisInit() {
// A logging handler is installed here. You can also install a custom error handler and memory
// allocator. By default errors are redirected to the logging handler
Noesis::GUI::SetLogHandler([](const char*, uint32_t, uint32_t level, const char*, const char* msg)
{
// [TRACE] [DEBUG] [INFO] [WARNING] [ERROR]
const char* prefixes[] = { "T", "D", "I", "W", "E" };
printf("[NOESIS/%s] %s\n", prefixes[level], msg);
});
// https://www.noesisengine.com/docs/Gui.Core.Licensing.html
Noesis::GUI::SetLicense(NS_LICENSE_NAME, NS_LICENSE_KEY);
// Noesis initialization. This must be the first step before using any NoesisGUI functionality
Noesis::GUI::Init();
// Setup theme
NoesisApp::SetThemeProviders();
Noesis::GUI::LoadApplicationResources("Theme/NoesisTheme.LightLime.xaml");
// For simplicity purposes we are not using resource providers in this sample. ParseXaml() is
// enough if there is no extra XAML dependencies
Noesis::Ptr<Noesis::Grid> xaml(Noesis::GUI::ParseXaml<Noesis::Grid>(R"(
<Grid xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Background="Green"
HorizontalAlignment="Center"
VerticalAlignment="Center">
<ScrollViewer Margin="10"
Background="Red"
Width="160"
Height="100"
VerticalScrollBarVisibility="Auto">
<TextBlock Padding="8 8 20 20"
FontSize="16"
Width="160"
TextWrapping="Wrap"
Text="adfkjakfdjka asd fads a dkw wlasa sdasdfasdf asd f asdf asdfdaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaasdf asdf df asdf afadsf asdf asdf sdf adsf asdf1 11133 444444444445 55." />
</ScrollViewer>
</Grid>
)"));
// View creation to render and interact with the user interface
// We transfer the ownership to a global pointer instead of a Ptr<> because there is no way
// in GLUT to do shutdown and we don't want the Ptr<> to be released at global time
_view = Noesis::GUI::CreateView(xaml).GiveOwnership();
_view->SetFlags(Noesis::RenderFlags_PPAA | Noesis::RenderFlags_LCD);
_view->SetSize(800, 600);
// Renderer initialization with an OpenGL device
_view->GetRenderer()->Init(NoesisApp::GLFactory::CreateDevice(false));
}
// process all input: query GLFW whether relevant keys are pressed/released this frame and react accordingly
// ---------------------------------------------------------------------------------------------------------
void processInput(GLFWwindow* pWwindow)
{
if (glfwGetKey(pWwindow, GLFW_KEY_ESCAPE) == GLFW_PRESS) {
glfwSetWindowShouldClose(pWwindow, true);
}
}
// glfw: whenever the window size changed (by OS or user resize) this callback function executes
// ---------------------------------------------------------------------------------------------
void cbFramebufferSize(GLFWwindow* pWnd, int w, int h)
{
// make sure the viewport matches the new window dimensions; note that width and
// height will be significantly larger than specified on retina displays.
glViewport(0, 0, w, h);
_view->SetSize(w, h);
}
//---------------------------------------------------------------
void myCreateFramebuffer()
{
glGenFramebuffers(1, &fbo);
glBindFramebuffer(GL_FRAMEBUFFER, fbo);
glGenTextures(1, &textColorBuffer);
glBindTexture(GL_TEXTURE_2D, textColorBuffer);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, SCR_WIDTH, SCR_HEIGHT, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glBindTexture(GL_TEXTURE_2D, 0);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, textColorBuffer, 0);
unsigned int rbo;
glGenRenderbuffers(1, &rbo);
glBindRenderbuffer(GL_RENDERBUFFER, rbo);
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, SCR_WIDTH, SCR_HEIGHT);
glBindRenderbuffer(GL_RENDERBUFFER, 0);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, rbo);
if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) {
printf("Framebuffer is not complete!\n");
}
glBindFramebuffer(GL_FRAMEBUFFER, 0);
}
//----------------------------------------------------------------------
void mySetupGlfw()
{
glfwInit();
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
glfwWindowHint(GLFW_TRANSPARENT_FRAMEBUFFER, GLFW_FALSE);
glfwWindowHint(GLFW_DECORATED, GLFW_TRUE);
pWindow = glfwCreateWindow(SCR_WIDTH, SCR_HEIGHT, "Demo", nullptr, nullptr);
if (pWindow == nullptr) {
std::cout << "Failed to create GLFW window" << std::endl;
glfwTerminate();
return;
}
glfwSetWindowPos(pWindow, 800, 600);
glfwMakeContextCurrent(pWindow);
glfwSetFramebufferSizeCallback(pWindow, cbFramebufferSize);
//if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)) {
// std::cout << "Failed to initialize GLAD" << std::endl;
// return;
//}
glfwSwapInterval(1);
}
//------------------------------------------------------------------------
void mySetupTriangle() {
glGenVertexArrays(1, &triangleVAO);
glGenBuffers(1, &triangleVBO);
glBindVertexArray(triangleVAO);
glBindBuffer(GL_ARRAY_BUFFER, triangleVBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(triangleVertices), triangleVertices, GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);
glEnableVertexAttribArray(0);
}
//------------------------------------------------------------------------
void myDrawTriangle(unsigned int targetFbo) {
glBindFramebuffer(GL_FRAMEBUFFER, targetFbo);
glClearColor(0.1f, 0.3f, 0.3f, 0.0f);
glClearStencil(0);
glClear(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
glUseProgram(shaderProgram);
glBindVertexArray(triangleVAO);
glDisable(GL_DEPTH_TEST);
glBindTexture(GL_TEXTURE_2D, textColorBuffer);
glDrawArrays(GL_TRIANGLES, 0, numTriangleVertices);
}
Re: scrollviewer content overflow flashing bug
Your code is not correct. Please, make sure to follow our tutorials and examples. The correct, per frame steps are:
1. Noesis Update
2. Noesis UpdateRenderTree
3. Noesis RenderOffscreen
4. Bind main framebuffer and set viewport
5. Render your triangle
6. Noesis Render
If you need more complex scenarios, I recommend RenderDoc for capturing the frame and understand what's happening. After invoking RenderOffscreen or Render the GPU state may have changed and you need to restore it (even the active framebuffer and viewport dimensions, RenderOffscreen may change it)
1. Noesis Update
2. Noesis UpdateRenderTree
3. Noesis RenderOffscreen
4. Bind main framebuffer and set viewport
5. Render your triangle
6. Noesis Render
If you need more complex scenarios, I recommend RenderDoc for capturing the frame and understand what's happening. After invoking RenderOffscreen or Render the GPU state may have changed and you need to restore it (even the active framebuffer and viewport dimensions, RenderOffscreen may change it)
Re: scrollviewer content overflow flashing bug
Thx, I fixed the issue as you said.Your code is not correct. Please, make sure to follow our tutorials and examples. The correct, per frame steps are: ...
The point of the question is:
don't set this line "_view->SetSize(SCR_WIDTH, SCR_HEIGHT);" in NoesisInit().
and set that line in main loop, it will be success.
Code: Select all
#define GLEW_STATIC
#include <GL/glew.h>
#include <GLFW/glfw3.h>
#include <NsGui/IView.h>
#include <NsGui/IRenderer.h>
#include <NsGui/TextBlock.h>
#include <NsApp/ThemeProviders.h>
#include <NsGui/FontProperties.h>
#include <NsGui/Grid.h>
#include <NsGui/IntegrationAPI.h>
#include <NsRender/GLFactory.h>
#include <NsRender/GLRenderDeviceApi.h>
#include <NsGui/Uri.h>
#include <iostream>
#include <cstdio>
const unsigned int SCR_WIDTH = 800;
const unsigned int SCR_HEIGHT = 600;
Noesis::IView* _view;
GLFWwindow* pWindow;
unsigned int triangleVBO, triangleVAO, shaderProgram;
float triangleVertices[] = {
-0.5f, -0.5f, 0.0f,
0.5f, -0.5f, 0.0f,
0.0f, 0.5f, 0.0f
};
const char* vertexShaderSource = "#version 330 core\n"
"layout (location = 0) in vec3 aPos;\n"
"void main()\n"
"{\n"
" gl_Position = vec4(aPos.x, aPos.y, aPos.z, 1.0);\n"
"}\0";
const char* fragmentShaderSource =
"#version 330 core\n"
"out vec4 FragColor;\n"
"void main()\n"
"{"
" FragColor = vec4(1.0f, 0.5f, 0.2f, 1.0f);"
"}\0";
void NoesisInit()
{
// A logging handler is installed here. You can also install a custom error handler and memory
// allocator. By default errors are redirected to the logging handler
Noesis::GUI::SetLogHandler([](const char*, uint32_t, uint32_t level, const char*, const char* msg)
{
// [TRACE] [DEBUG] [INFO] [WARNING] [ERROR]
const char* prefixes[] = { "T", "D", "I", "W", "E" };
printf("[NOESIS/%s] %s\n", prefixes[level], msg);
});
// https://www.noesisengine.com/docs/Gui.Core.Licensing.html
Noesis::GUI::SetLicense(NS_LICENSE_NAME, NS_LICENSE_KEY);
// Noesis initialization. This must be the first step before using any NoesisGUI functionality
Noesis::GUI::Init();
// Setup theme
NoesisApp::SetThemeProviders();
Noesis::GUI::LoadApplicationResources("Theme/NoesisTheme.DarkBlue.xaml");
// For simplicity purposes we are not using resource providers in this sample. ParseXaml() is
// enough if there is no extra XAML dependencies
Noesis::Ptr<Noesis::Grid> xaml(Noesis::GUI::ParseXaml<Noesis::Grid>(R"(
<Grid xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Background="Green"
HorizontalAlignment="Center"
VerticalAlignment="Center" >
<ScrollViewer Margin="10"
Background="Red"
Width="160"
Height="100"
VerticalScrollBarVisibility="Auto">
<TextBlock Padding="8 8 20 20"
FontSize="16"
Width="160"
TextWrapping="Wrap"
Text="adfkjakfdjka asd fads a dkw wlasa sdasdfasdf asd f asdf asdfdaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaasdf asdf df asdf afadsf asdf asdf sdf adsf asdf1 11133 444444444445 55." />
</ScrollViewer>
</Grid>
)"));
// View creation to render and interact with the user interface
// We transfer the ownership to a global pointer instead of a Ptr<> because there is no way
// in GLUT to do shutdown and we don't want the Ptr<> to be released at global time
_view = Noesis::GUI::CreateView(xaml).GiveOwnership();
_view->SetFlags(Noesis::RenderFlags_PPAA | Noesis::RenderFlags_LCD);
// Renderer initialization with an OpenGL device
_view->GetRenderer()->Init(NoesisApp::GLFactory::CreateDevice(false));
}
//====================================================================================
int main()
{
glfwInit();
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
pWindow = glfwCreateWindow(SCR_WIDTH, SCR_HEIGHT, "Demo", nullptr, nullptr);
if (pWindow == nullptr) {
std::cout << "Failed to create GLFW window" << std::endl;
glfwTerminate();
return 0;
}
glfwMakeContextCurrent(pWindow);
glfwSwapInterval(1);
GLenum glew_err = glewInit();
if (glew_err != GLEW_OK)
{
throw std::runtime_error(std::string("Error initializing GLEW, error: ") + (const char*)glewGetErrorString(glew_err));
return 0;
}
NoesisInit();
unsigned int vertexShader;
vertexShader = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(vertexShader, 1, &vertexShaderSource, NULL);
glCompileShader(vertexShader);
unsigned int fragmentShader;
fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(fragmentShader, 1, &fragmentShaderSource, NULL);
glCompileShader(fragmentShader);
shaderProgram = glCreateProgram();
glAttachShader(shaderProgram, vertexShader);
glAttachShader(shaderProgram, fragmentShader);
glLinkProgram(shaderProgram);
glDeleteShader(vertexShader);
glDeleteShader(fragmentShader);
glGenVertexArrays(1, &triangleVAO);
glGenBuffers(1, &triangleVBO);
glBindVertexArray(triangleVAO);
glBindBuffer(GL_ARRAY_BUFFER, triangleVBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(triangleVertices), triangleVertices, GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);
glEnableVertexAttribArray(0);
while (!glfwWindowShouldClose(pWindow)) {
_view->Update(glfwGetTimerValue() / 1000.0f);
_view->GetRenderer()->UpdateRenderTree();
_view->GetRenderer()->RenderOffscreen();
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glViewport(0, 0, SCR_WIDTH, SCR_HEIGHT);
_view->SetSize(SCR_WIDTH, SCR_HEIGHT);
glDisable(GL_SCISSOR_TEST);
//glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
glClearColor(0.0f, 0.0f, 0.25f, 0.0f);
glClearStencil(0);
glClear(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
glUseProgram(shaderProgram);
glBindVertexArray(triangleVAO);
glDrawArrays(GL_TRIANGLES, 0, 3);
_view->GetRenderer()->Render();
glfwSwapBuffers(pWindow);
glfwPollEvents();
}
_view->GetRenderer()->Shutdown();
_view->Release();
glfwTerminate();
return 0;
}
Who is online
Users browsing this forum: Google [Bot] and 3 guests