Context creation fails - c++

I'm learning OpenGL so I was experimenting with drawing 2D images.
I first put everything in the main function of my C++ program. It worked fine (2 triangles were drawn).
I decided to make the program clearer by making separate classes, ...
But now it isn't working anymore. When I want to make the OpenGL Context, it fails. When I display the error I get :
Failed creating OpenGL context at version requested
In the tutorial I am reading they said this error is most likely due to the fact that the version of OpenGL isn't supported by your graphics card, but if this was the case, it shouldn't work when I put all the code in the main procedure.
This is the part where it goes wrong (context creation) :
bool OpenGL_Scene::initializeWindow() {
// Initialize the SDL
if(SDL_Init(SDL_INIT_VIDEO) < 0)
{
cout << "Error while initializing the SDL : " << SDL_GetError() << endl;
SDL_Quit();
return false;
}
// Configure OpenGL
// Use version 3.1
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3); // OpenGL 3.x
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 1); // OpenGL x.1 --> OpenGL 3.1
// Double buffering
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); // Use double buffering (0 to not use it)
SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24); // Buffer has a depth of 24 bits
// Make the window
this->window = SDL_CreateWindow(this->windowTitle.c_str(), SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, this->windowWidth, this->windowHeight, SDL_WINDOW_SHOWN | SDL_WINDOW_OPENGL); // SDL_WINDOW_OPENGL necessary to specify that the window will have an OpenGL context attached to it.
if(this->window == 0) // Initialization failed
{
cout << "Error while creating the window : " << SDL_GetError() << endl;
SDL_Quit();
return false;
}
// Make the OpenGL context given the SDL window
this->OpenGL_Context = SDL_GL_CreateContext(this->window);
// Make sure the creation of the context succeeded. If not the problem is probably that the version of OpenGL isn't supported by the graphics card.
if(this->OpenGL_Context == 0)
{
cout << "Could not create the OpenGL context : " << SDL_GetError() << endl;
SDL_DestroyWindow(window);
SDL_Quit();
return false;
}
return true;
};
In the last few lines the error get displayed so the program results in :
Could not create the OpenGL context : Failed creating OpenGL context at version requested
I searched a lot to find a solution and found this :
SO topic
So in the above code I tried :
// Configure OpenGL
// Use version 3.1
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3); // OpenGL 3.x
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 1); // OpenGL x.1 --> OpenGL 3.1
// Double buffering
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE); // ADDING THIS AVOIDS THAT THE CONTEXT COULD NOT BE CREATED BUT THEN WHEN WE DRAW SOMETHING WE DON'T SEE ANYTHING
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); // Use double buffering (0 to not use it)
SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24); // Buffer has a depth of 24 bits
Now when I run the program with this extra line, the context is created (without errors so OpenGL_Context != 0) but nothing is drawn. I omitted the part of the code where I am drawing, because it worked before and I didn't changed anything.
Does someone has an idea what could be the problem?
PS : I'm working on a Macbook Pro (OS X Yosemite (10.10.4)) and my graphics card is an NVIDIA GeForce GT 650M 1024 MB
EDIT : I tried debugging the code that draws the triangles but I really don't see the error (mainly because I'm really really new to OpenGL). Underneath you can find the drawing code. Notice that I don't initialize GLEW anymore as it isn't necessary (according to the comments).
void OpenGL_Scene::mainLoop() {
bool end = false;
// Make vertices (punten) in a table
// !!! WARNING : Use 1 table for ALL vertices !!! Don't use a separate table for each of the forms, this would slow down the program because you have to send each of the tables to OpenGL !!!
float vertices[] = {-0.5, -0.5, 0.0, 0.5, 0.5, -0.5, // 3 Points for first triangle --> (-0.5, -0.5) , (0.0, 0.5) and (0.5, -0.5) (All in (x, y) --> 2D)
-0.8, -0.8, -0.3, -0.8, -0.8, -0.3}; // 3 Points for second triangle
// Before we start drawing, clear the screen
glClear(GL_COLOR_BUFFER_BIT);
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, vertices);
glEnableVertexAttribArray(0); // Activate the table we passed to OpenGL using the identifier (index) passed to OpenGL (in this case 0)
// Now that OpenGL knows which vertices it has to display we are going to specify what it has to do with these vertices
glDrawArrays(GL_TRIANGLES, 0, 6); // Draw both triangles
glDisableVertexAttribArray(0); // Because it isn't necessary anymore
SDL_GL_SwapWindow(this->window); // Refresh the screen
while(!end) {
// Listen to events and play with them
SDL_WaitEvent(&this->events); // Will wait for an event and assign it to "events" variable
if(this->events.window.event == SDL_WINDOWEVENT_HIDDEN)
cout << "The user has hidden the window !" << endl;
else if(this->events.window.event == SDL_WINDOWEVENT_CLOSE) {
cout << "The user closed the window !" << endl;
glClear(GL_COLOR_BUFFER_BIT); // Clear the screen
SDL_GL_SwapWindow(this->window); // Refresh the window
end = true;
}
}
// Quitting the SDL and OpenGL properly is done by the destructor
}
So now when I execute the project, first I make the window (this is succesfull) and then I call the mainLoop procedure (from above).
I stepped trough the drawing code using the debugger, all the procedures were called (glClear, ...) but nothing appears in the window (it stays black).

I found the error. I was initializing OpenGL after initializing the SDL, this is why the context could not be created without forcing to go into "Core Profile".
The correct order in "initializeWindow" is :
// Configure OpenGL
// Use version 3.1
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3); // OpenGL 3.x
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 1); // OpenGL x.1 --> OpenGL 3.1
// Double buffering
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); // Use double buffering (0 to not use it)
SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24); // Buffer has a depth of 24 bits
// Initialize the SDL
if(SDL_Init(SDL_INIT_VIDEO) < 0)
{
cout << "Error while initializing the SDL : " << SDL_GetError() << endl;
SDL_Quit();
return false;
}
Doing so the context is created successfully.

Related

Why is OpenGL telling me that terminate called after throwing an instance of 'int' after running it?

So I tried to make an OpenGL project with GLFW and glad in visual studio code, but it would throw and error when I would compile and run the program.
I tried to make 3 triangles in a window, it worked so I tried organizing the VBO, VAO, EBO, shaderProgram, vertexShaderSource, and fragmentShaderSource into individual files, and compiled and ran it, I expected the usual result but would give me a window that is not responding, then it would terminate and give out an error. I'm not sure witch of the files are causing this, but my guess is the main.cpp file:
#include"header/shaderClass.h"
#include"header/VAO.h"
#include"header/VBO.h"
#include"header/EBO.h"
//some vertex and indices arrays here
int main()
{
// Initialize GLFW
glfwInit();
// Tell GLFW what version of OpenGL we are using
// In this case we are using OpenGL 3.3
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
// Tell GLFW we are using the CORE profile
// So that means we only have the modern functions
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
// Create a GLFWwindow object of 800 by 800 pixels, naming it "YoutubeOpenGL"
GLFWwindow* window = glfwCreateWindow(800, 800, "YoutubeOpenGL", NULL, NULL);
// Error check if the window fails to create
if (window == NULL)
{
std::cout << "Failed to create GLFW window" << std::endl;
glfwTerminate();
return -1;
}
// Introduce the window into the current context
glfwMakeContextCurrent(window);
//Load GLAD so it configures OpenGL
gladLoadGL();
// Specify the viewport of OpenGL in the Window
// In this case the viewport goes from x = 0, y = 0, to x = 800, y = 800
glViewport(0, 0, 800, 800);
// Generates Shader object using shaders defualt.vert and default.frag
Shader shaderProgram("default.vert", "default.frag");
// Generates Vertex Array Object and binds it
VAO VAO1;
VAO1.Bind();
// Generates Vertex Buffer Object and links it to vertices
VBO VBO1(vertices, sizeof(vertices));
// Generates Element Buffer Object and links it to indices
EBO EBO1(indices, sizeof(indices));
// Links VBO to VAO
VAO1.LinkVBO(VBO1, 0);
// Unbind all to prevent accidentally modifying them
VAO1.Unbind();
VBO1.Unbind();
EBO1.Unbind();
// Main while loop
while (!glfwWindowShouldClose(window))
{
// Specify the color of the background
glClearColor(0.07f, 0.13f, 0.17f, 1.0f);
// Clean the back buffer and assign the new color to it
glClear(GL_COLOR_BUFFER_BIT);
// Tell OpenGL which Shader Program we want to use
shaderProgram.Activate();
// Bind the VAO so OpenGL knows to use it
VAO1.Bind();
// Draw primitives, number of indices, datatype of indices, index of indices
glDrawElements(GL_TRIANGLES, 9, GL_UNSIGNED_INT, 0);
// Swap the back buffer with the front buffer
glfwSwapBuffers(window);
// Take care of all GLFW events
glfwPollEvents();
}
// Delete all the objects we've created
VAO1.Delete();
VBO1.Delete();
EBO1.Delete();
shaderProgram.Delete();
// Delete window before ending the program
glfwDestroyWindow(window);
// Terminate GLFW before ending the program
glfwTerminate();
return 0;
}

Regular window screen capture using openGL

I'm trying to my desktop image capture. (All images, including the desktop output to the monitor)
It's easy using window API (BitBlt or CImageClass) and it's not the way I want.
I want do it using opengl. so I found glReadPixel funtion and window TRANSPARENT.
But it just read pixel own Windows application screen.(Save as bmp file and check)
Initialize()
glfwSetErrorCallback(errorCallback);
if (!glfwInit()) {
std::cerr << "Error: GLFW " << std::endl;
exit(EXIT_FAILURE);
}
glfwWindowHint(GLFW_DEPTH_BITS, 16);
glfwWindowHint(GLFW_TRANSPARENT_FRAMEBUFFER, GLFW_TRUE);
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
glfwWindowHint(GLFW_SAMPLES, 4);
const int Monitor_count = GetMonitors();
GLwindow = glfwCreateWindow(
nWidth, // width
nHeight, // height
"OpenGL_Test", // window title
NULL, NULL);
if (!GLwindow) {
glfwTerminate();
exit(EXIT_FAILURE);
}
glfwSwapInterval(1);
if (glfwGetWindowAttrib(GLwindow, GLFW_TRANSPARENT_FRAMEBUFFER))
{
//...
}
glfwSetWindowOpacity(GLwindow, 0.0f);
auto Mode = glfwGetVideoMode(Monitor[0]);
glfwMakeContextCurrent(GLwindow);
glfwSetKeyCallback(GLwindow, keyCallback);
glewExperimental = GL_TRUE;
GLenum errorCode = glewInit();
if (GLEW_OK != errorCode) {
std::cerr << "Error: GLEW - " << glewGetErrorString(errorCode) << std::endl;
glfwTerminate();
exit(EXIT_FAILURE);
}
if (!GLEW_VERSION_3_3) {
std::cerr << "OpenGL 3.3 API is not available." << std::endl;
glfwTerminate();
exit(EXIT_FAILURE);
}
glViewport(0, 0, nWidth, nHeight);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
if (glCheckFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE) {
std::cerr << "Error: " << std::endl;
}
return true;
Roop
while (!glfwWindowShouldClose(GLwindow)) {
Sleep(10);
glClearColor(0.0f, 0.3f, 0.3f, 0.5f);
glClear(GL_COLOR_BUFFER_BIT);
unsigned char *image = (unsigned char*)malloc(sizeof(unsigned char)*nWidth*nHeight * 3);
glReadPixels(0, 0, nWidth, nHeight, GL_BGR_EXT, GL_UNSIGNED_BYTE, image);
glfwPollEvents();
}
return true;
Q1. Is it possible desktop capture(Full Image GPU output) with OPENGL?
Q2. If Q1 is possible, Should I use FBO and PBO GL_BACK??
Q3. How to access to mother window or GPU adapter? >> GL seems to strongly reject this.(I don't want any rendering, just read pixel data from GPU(Desktop image. not rendered by my application.)(If it is possible ...))
Anybody shows to me about link or idea?
What you're asking for is something completely outside the scope of OpenGL. OpenGL is designed to be a platform-agnostic API for applications to talk about drawing stuff into framebuffers in an abstract fashion. OpenGL has no notion of windows*, screens, or a desktop. OpenGL doesn't operate at a level where such concepts exist. Heck, OpenGL doesn't even know what a GPU is. OpenGL is supposed to be initialized through platform-specific mechanisms to establish a context which assigns actual meaning to OpenGL API calls. As far as I know, there is no way to set up an OpenGL context with a framebuffer whose contents would somehow correspond to the desktop on Windows (or any other platform I'm aware of). As far as my understanding goes, this wouldn't really make sense…
To do what you want to do, you'll have to rely on the respective platform-specific APIs. The probably simplest way on Windows is to get an HDC for the entire desktop and BitBlt from there. See, e.g., this question for more on that. A more modern approach would be to use the DXGI Desktop Duplication API.
(*) yes, I know the OpenGL specification technically does talk about "windows" in a few places; but it only really does so when it's talking about all the things it's not responsible for…
I'm trying to my desktop image capture. (All images, including the desktop output to the monitor)
It's easy using window API (BitBlt or CImageClass) and it's not the way I want.
But it's the way it's supposed to be done.
I want do it using opengl. so I found glReadPixel funtion
You can't. OpenGL doesn't "know" about the desktop, or other windows (or actually what windows are at all). The function glReadPixels will work reliably only for images that have been drawn with OpenGL itself.
You can't use OpenGL to take screenshots! On older computers it might seem to work, but that's only because of their older memory management where when you create a new window, its memory will be "cut" from what was below and if you read that, it looks like a way to make screenshots. But it is not.

glew causes screen to flicker between red and black. glad works

I'm doing my programming on MacOS 10.14.3 that has support for OpenGL 4.1.
I'm using glfw for the ui and glew for the extensions detection.
this is the my code so far:
#include <iostream>
#include <GL/glew.h>
#include <GLFW/glfw3.h>
const GLint WIDTH = 800, HEIGHT = 600;
int main() {
if (!glfwInit()) {
std::cout << "GLFW initialisation Failed";
glfwTerminate();
return 1;
}
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR,4);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR,1);
// Core profile = No Backwards Compatibility
glfwWindowHint(GLFW_OPENGL_PROFILE,GLFW_OPENGL_CORE_PROFILE);
// Allow forward compatibility
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT,GL_TRUE);
GLFWwindow *mainWindow = glfwCreateWindow(WIDTH, HEIGHT, "Test Window", nullptr, nullptr);
if (!mainWindow) {
std::cout << "GLFW window creation Failed!";
glfwTerminate();
return 1;
}
// get buffer size information
int bufferWidth, bufferHeight;
glfwGetFramebufferSize(mainWindow,&bufferWidth,&bufferHeight);
// Set context for GLEW to use
glfwMakeContextCurrent(mainWindow);
// Allow modern extension features
glewExperimental = GL_TRUE;
if (glewInit() != GLEW_OK) {
std::cout << "GLEW initialisation Failed!";
glfwDestroyWindow(mainWindow);
glfwTerminate();
return 1;
}
// Setup viewport size
glViewport(0,0,bufferWidth,bufferHeight);
while(!glfwWindowShouldClose(mainWindow)) {
// Get + handle user input events
glfwPollEvents();
// Clear window
glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
glfwSwapBuffers(mainWindow);
}
return 0;
}
this should be a basic started for an opengl application. it should init glfw and glew and paint the screen in red, and on top of that I can add my opengl drawing/rendering functions.
when I execute it instead of seeing a window with a red background color, the background color flickers between red and black.
any ideas why?
update
it appears that the screen flickers between black and red even if I choose a different color with glClearColor.
starting to think maybe glew isn't working properly.. i'll move back to glad and seee if there is any difference.
update 2
replaced glew with glad by removed glew code, generating glad code using the web interface, then included glad.h and added glad.c to compilation, and initialised glad with:
if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)) {
std::cout << "Failed to initialize GLAD" << std::endl;
return -1;
}
ok now that works properly... but I want to use glew... what may be the problem that's causing this ?

OpenGL cannot draw with glVertexAttrib in core profile

I want to use OpenGL 3.1.
I'm using a Macbook Pro with 2 graphic cards: NVIDIA GeForce GT 650M 1024 MB, and Intel HD Graphics 4000 1536 MB. They both support up to OpenGL 4.1.
Previously i was able to draw a triangle however, my program was using version 2.1. Therefore I added: SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);. However, now the triangle is no longer drawn.
#include <string>
#include <iostream>
#include <SDL2/SDL.h>
#define GL3_PROTOTYPES 1
#include "../include/GL3/gl3.h"
int main(int argc, const char *argv[]) {
// Initialize the SDL
if(SDL_Init(SDL_INIT_VIDEO) < 0) {
std::cout << "Failed to initialize the SDL: " << SDL_GetError() << std::endl;
SDL_Quit();
return -1;
}
// Configure the SDL to use OpenGL 3.1
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 1);
// ======= HERE =======
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
// ====================
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24);
SDL_Window* window = SDL_CreateWindow("Triangle Test", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 800, 600, SDL_WINDOW_SHOWN | SDL_WINDOW_OPENGL);
if (window == 0) {
std::cout << "Error when creating the window: " << SDL_GetError() << std::endl;
SDL_Quit();
return -1;
}
// Create the OpenGL context
SDL_GLContext contextOpenGL = SDL_GL_CreateContext(window);
// Initialization may fail
if (contextOpenGL == 0) {
std::cout << SDL_GetError() << std::endl;
SDL_DestroyWindow(window);
SDL_Quit();
return -1;
}
SDL_Event events;
bool end = false;
// Define the vertices of our triangle
static const GLfloat vertices[] = {0.0, 1.0, // left point
-0.5, 0.0, // right point
0.5, 0.0}; // upper point
const int TRIANGLE_IDX = 0;
while(!end) {
SDL_WaitEvent(&events);
if(events.window.event == SDL_WINDOWEVENT_CLOSE) {
end = true;
}
// Clear the screen
glClear(GL_COLOR_BUFFER_BIT);
// Send vertices to OpenGL
glVertexAttribPointer(TRIANGLE_IDX, 2, GL_FLOAT, GL_FALSE, 0, vertices);
// Activate our vertex array
glEnableVertexAttribArray(TRIANGLE_IDX);
// Draw the points passed previously
glDrawArrays(GL_TRIANGLES, 0, 3);
glDisableVertexAttribArray(TRIANGLE_IDX);
// Refresh the screen
SDL_GL_SwapWindow(window);
}
return 0;
}
I tried to first use glGenBuffers, glBindBuffer and glBufferData but i could not manage to make it work.
The Fixed Function Pipeline has been removed from core OpenGL 3.1 and above.
You will have to use shaders instead. This site has a nice example of how to use them.

OpenGL Depth Testing not working (GLEW/SDL2)

I am working on a simple opengl rendering engine as a project to learn C++ and OpenGL. I am following along with a youtube tutorial series that does it in java (which I know) and translating it to C++.
I'm hitting a snag trying to render a cube from an OBJ file that I read in with Assimp. It appears I haven't setup depth testing/culling correctly but can't for the life of me figure out what I am doing wrong. It appears that faces on the back of the object are not getting culled and are rendering over faces that are in front of them.
Images of cube rendering with some back faces being rendered over front faces:
I am using GLEW + SDL2 to initialize opengl and create a window.
I have made sure to set the following when initializing:
Window::Window(const int width, const int height, const std::string& title)
{
m_isClosed = false;
RenderUtil::initGraphics();
m_window = SDL_CreateWindow(title.c_str(), SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, width, height, SDL_WINDOW_OPENGL);
m_glContext = SDL_GL_CreateContext(m_window);
glewExperimental = GL_TRUE;
GLenum status = glewInit();
if (status != GLEW_OK) {
std::cerr << "WARNING WILL ROBINSON!" << std::endl;
std::cerr << "GLEW failed to initialize" << std::endl;
std::cerr << "GLEW Error Code: " << status << std::endl;
std::cerr << "GLEW Error Message: " << glewGetErrorString(status);
exit(1);
}
}
void RenderUtil::initGraphics() {
SDL_Init(SDL_INIT_EVERYTHING);
SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8);
SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8);
SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8);
SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, 8);
SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 16);
SDL_GL_SetAttribute(SDL_GL_BUFFER_SIZE, 32);
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
glEnable(GL_CULL_FACE);
glCullFace(GL_BACK);
glEnable(GL_DEPTH_TEST);
glEnable(GL_FRAMEBUFFER_SRGB);
}
During the program loop I make sure to clear the buffers as well
void RenderUtil::clearScreen() {
// TODO: stencil buffer
glClearColor(RU_CLEAR_R, RU_CLEAR_G, RU_CLEAR_B, RU_CLEAR_A);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
}
I'm really at a loss as to what would be causing this. Full Code for the project can be found at GitHub In case there is something missing from the question that I didn't know to add.
Thanks in Advance for the Help!
OpenGL state changes are only possible when a valid context is available. In your program, you are trying to enable the depth test before the context has been created.
Moving glEnable(GL_DEPTH_TEST) after SDL_GL_CreateContext should solve the problem.