Visual Studio Dynamic Library: OpenGL don't create window - c++

I have a problem. I decided to make an interface so that I can override functions for OpenGL, DirectX and so on ..
The problem is that opengl window is not being created in my dynamic project. But when I create a window without a dynamic library, then the window is created without problems.
Why, when I try to create a window through a dynamic library, it is not created?
Below I will briefly provide the project structure
My visual studio solution consists of two projects: GLRenderSystem and MeshEditor
GLRenderSystem - dynamic library. Here I have two classes declared, GLRenderSystem.h, GLWindow.h which will inherit from the IRenderSystem and IWindow interfaces:
GLWindow.h:
#pragma once
#ifndef _GL_WINDOW_
#define _GL_WINDOW_
#include "../Interfaces/IWindow.h"
#include <glfw\glfw3.h>
class GLWindow : public IWindow
{
public:
GLWindow(const std::string& title, uint32_t width, uint32_t height);// Window is not creating.
~GLWindow();
uint32_t getWidth() const;
uint32_t getHeight() const;
GLFWwindow* getGLFWHandle() const;
private:
GLFWwindow* glfwHandle;
};
#endif
GLWindow.cpp:
#include "pch.h"
#include "GLWindow.h"
#include<iostream>
GLWindow::GLWindow(const std::string & title, uint32_t width, uint32_t height)
{
glfwHandle = glfwCreateWindow(width, height, title.data(), nullptr, nullptr); // ALWAYS NULL POINTER RETURNS
glfwMakeContextCurrent(glfwHandle);
static bool initGLAD = false;
if (!initGLAD)
{
initGLAD = true;
gladLoadGLLoader((GLADloadproc)glfwGetProcAddress);
}
......
Also Exports.h and Exports.cpp with functions neede to create IRenderSystem and IWindow in the main MeshEditor
Exports.h:
#pragma once
#include <string>
#ifdef OGL_RENDER_SYSTEM_EXPORT
#define OGL_RENDER_SYSTEM_API __declspec(dllexport)
#else
#define OGL_RENDER_SYSTEM_API __declspec(dllimport)
#endif
class IRenderSystem;
class IWindow;
extern "C" OGL_RENDER_SYSTEM_API IRenderSystem* createRenderSystem();
extern "C" OGL_RENDER_SYSTEM_API IWindow* createWindow(const std::string& title, uint32_t width, uint32_t height);
...
Exports.cpp:
#include "pch.h"
#include "Exports.h"
#include "GLWindow.h"
#include "GLRenderSystem.h"
#include<iostream>
OGL_RENDER_SYSTEM_API IRenderSystem * createRenderSystem()
{
return new GLRenderSystem;
}
OGL_RENDER_SYSTEM_API IWindow * createWindow(const std::string & title, uint32_t width, uint32_t height)
{
return new GLWindow(title, width, height);
}
...
And finally, the MeshEditor project, where from main.cpp I try to create a window using a dynamic library
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtx/transform.hpp>
#include "../Interfaces/IWindow.h"
#include "../Interfaces/IRenderSystem.h"
#include "DynamicLibrary.h"
#include<iostream>
int main()
{
DynamicLibrary dll("GLRenderSystem.dll");
auto createRenderSystem = dll.getSymbol<IRenderSystem* (*)()>("createRenderSystem");
auto createWindow = dll.getSymbol<IWindow* (*)(const std::string& title, uint32_t width, uint32_t height)>("createWindow");
auto waitEvents = dll.getSymbol<void(*)()>("waitEvents");
auto swapDisplayBuffers = dll.getSymbol<void(*)(IWindow* window)>("swapDisplayBuffers");
auto windowShouldClose = dll.getSymbol<bool(*)(IWindow* window)>("windowShouldClose");
IRenderSystem* rs = createRenderSystem();
IWindow* window = createWindow("myWindow", 640, 480); // ALWAYS NULL POINTER RETURNS
rs->init();
rs->setupLight(0, glm::vec3{ 0,5,0 }, glm::vec3{ 1,0,0 }, glm::vec3{ 0,1,0 }, glm::vec3{ 0,0,1 });
rs->turnLight(0, true);
while (!windowShouldClose(window))
{
rs->setViewport(0, 0, window->getWidth(), window->getHeight());
rs->clearDisplay(0.5f, 0.5f, 0.5f);
renderScene(*rs);
swapDisplayBuffers(window);
waitEvents();
}
delete window;
delete rs;
return 0;
}
The problem is that the createWindow function in main.cpp always returns nullptr, that is, window is not created.

Related

Avoid ambiguity in C++

I am trying to implement a C++ wrapper alongside my C project.
So, for example, I have "window.h" which has the standard C include guard. It requires <stdlib.h> and <string.h> as well as some third party library includes.
Then, I have "window.hpp" which depends on "window.h", but uses C++ #pragma once and requires <cstdlib> and <string> for the C++ implementations.
I am running into an ambiguity issue where the C/C++ standard implementations are conflicting, and I'm not quite sure what to do about it. You can see I tried to fix this by simply checking if __cplusplus was defined, and only adding the C++ headers if that's the case.
The idea is that you can just do using namespace LittleEngine::utils; and it will include SDL and GLEW for you, as well as add some wrapper features for creating a window, for example; where it uses C++ features like classes instead of the C implemented methods.
For sanity's sake, that's why these are separate files and not just one header file that adds compatibility for both C and C++ with extern "C" { ... }.
"window.h"
#if __cplusplus
#pragma once
#endif
#ifndef LITTLE_ENGINE_UTILS_WINDOW_H_
#define LITTLE_ENGINE_UTILS_WINDOW_H_
#include <SDL2/SDL.h>
#include <GL/glew.h>
#if __cplusplus
# include <cstdio>
# include <string>
#else
# include <stdio.h>
# include <string.h>
#endif
typedef struct {
SDL_Window* window;
SDL_GLContext context;
SDL_Event event;
} Engine_GLWindow_t;
enum Engine_Window_Renderer {
VULKAN,
OPENGL
};
int Engine_CreateGLWindow(const char* title, Engine_GLWindow_t* window)
{
// Initialize SDL
if(SDL_Init(SDL_INIT_EVERYTHING) != 0)
{
fprintf(stderr, "Failed to initialize SDL.\n");
fprintf(stderr, "%s\n", SDL_GetError());
return -1;
}
// Configure window flags
Uint32 flags = 0;
flags |= SDL_WINDOW_OPENGL;
SDL_Window* sdlwin = SDL_CreateWindow(
title,
SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED,
800,
600,
flags
);
if(!sdlwin)
return -1;
window->window = sdlwin;
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 4);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 6);
SDL_GL_SetSwapInterval(1);
SDL_GLContext context;
if((context = SDL_GL_CreateContext(window->window)) != NULL)
window->context = context;
else
{
SDL_DestroyWindow(window->window);
fprintf(stderr, "Failed to initialize the GL context.\n");
fprintf(stderr, "%s\n", SDL_GetError());
return -1;
}
glewExperimental = GL_TRUE;
GLenum glewCode = glewInit();
if(glewCode != GLEW_OK)
{
SDL_GL_DeleteContext(window->context);
SDL_DestroyWindow(window->window);
fprintf(stderr, "Failed to initialize GLEW.\n");
fprintf(stderr, "%s\n", glewGetErrorString(glewCode));
return -1;
}
glEnable(GL_DEPTH_TEST);
glViewport(0, 0, 800, 600);
SDL_ShowWindow(sdlwin);
return 0;
}
int Engine_DestroyGLWindow(Engine_GLWindow_t* window)
{
SDL_GL_DeleteContext(window->context);
SDL_DestroyWindow(window->window);
SDL_Quit();
return 0;
}
#endif
"windows.hpp"
#pragma once
/*
file included as:
engine.hpp
...
namespace LittleEngine {
namespace utils {
# include "utils.hpp" // -> #include "windows.hpp"
}
}
*/
#include "window.h"
#include <cstdint>
class GLWindow {
public:
GLWindow(std::string title)
{
Engine_CreateGLWindow(title.c_str(), &this->window_data);
}
GLWindow(std::string title, bool& success)
{
if(Engine_CreateGLWindow(title.c_str(), &this->window_data) == 0)
success = true;
}
~GLWindow()
{
Engine_DestroyGLWindow(&this->window_data);
}
Engine_GLWindow_t* getWindowData()
{
return &this->window_data;
}
protected:
Engine_GLWindow_t window_data;
};
main.cpp
#include <LittleEngine/engine.hpp>
int main(int argc, char* argv[], char* envp[])
{
// COMMENTED CODE WORKS BTW
// Engine_GLWindow_t window;
// Engine_CreateGLWindow("LittleBird", &window);
LittleEngine::utils::GLWindow window("LittleBird");
bool should_run = true;
const LittleEngine::utils::Uint8* keys = nullptr;
while (should_run)
{
while (LittleEngine::utils::SDL_PollEvent(&window.getWindowData()->event))
if (window.getWindowData()->event.type == LittleEngine::utils::SDL_QUIT)
should_run = false;
// ensure that SDL2 updated the keyboard state
LittleEngine::utils::SDL_PumpEvents();
// // automatically update window size
// UpdateWindowSize(&window);
// SDL2 should automatically clear this memory after each loop
keys = LittleEngine::utils::SDL_GetKeyboardState(0);
// black background color
LittleEngine::utils::glClearColor(0.00f, 0.00f, 0.00f, 1.00f);
// red background color if pressing W
if(keys[LittleEngine::utils::SDL_SCANCODE_W])
LittleEngine::utils::glClearColor(1.00f, 0.00f, 0.00f, 1.00f);
LittleEngine::utils::glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
LittleEngine::utils::SDL_GL_SwapWindow(window.getWindowData()->window);
}
return 0;
}
So after some more testing, the answer to my problem was that you have to wrap C header files in extern "C" before trying to include them into namespaces.
namespace LittleEngine {
namespace utils {
extern "C" {
# include "window.h"
}
# include "window.hpp"
}
}
However, even when doing this, it still puts the C-defines at the root namespace, which makes sense I guess.
Edit: Moreover, it does get a lot weirder than just that. In the above example, I can extern-C include the "window.h" file. The second I hop to another file and try to chain impl. this, I get the same error I started out with. TLDR; TIL only C++ includes go in namespaces.
Edit 2: I think it was just GLEW and SDL causing the issue. I hate programming. Why do I do this to myself?
Edit 3: After even more testing.. I think it was. So the biggest changes I made when refactoring is
Not including headers in sub-header files. You can do this because of how the Linker works.
I took out all the extern "C" because all that should theoretically do is disable C++ name wrangling, which doesn't make sense anyway.
I simply moved the SDL and GLEW includes out of scope of the namespace and suddenly it works.
Either way, my point still stands. Don't include C headers in C++ namespaces.
If somebody else wants to answer this in a preferably more detailed manner, I would be happy to mark that as the answer.

Error with using wxWidgets alongside SFML

This error is with wxWidgets 3.1.5, and SFML 2.5.1
I have the following code:
(main.cpp) :-
#include <SFML/Graphics.hpp>
#include <wx/wx.h>
#include "wxSfmlCanvas.h"
#include "main.h"
TestFrame::TestFrame() :
wxFrame(NULL, wxID_ANY, "SFML 2.5 w/ wxWidgets 3.1", wxDefaultPosition, wxSize(650, 490))
{
mCanvas = new TestSfmlCanvas(this, wxID_ANY, wxPoint(5, 25), wxSize(640, 480));
// Also add a button.
wxButton *button = new wxButton(
this,
wxID_ANY,
wxT("Toggle Size"),
wxPoint(5, 5)
);
button->Bind(wxEVT_BUTTON, [&](wxCommandEvent& arg) -> void {
mCanvas->toggleSize();
});
wxBoxSizer* mainSizer = new wxBoxSizer( wxVERTICAL );
mainSizer->Add(mCanvas, 6, wxALIGN_TOP | wxEXPAND);
mainSizer->Add(button, 0, wxALIGN_RIGHT | wxALIGN_BOTTOM);
SetSizerAndFit(mainSizer);
}
TestSfmlCanvas::TestSfmlCanvas(
wxWindow* Parent,
wxWindowID Id,
wxPoint& Position,
wxSize& Size,
long Style
) : wxSfmlCanvas(Parent, Id, Position, Size, Style),
mLarge(false)
{
// Load a texture and create a sprite.
mTexture.loadFromFile("data/ball.png");
mSprite = std::make_unique<sf::Sprite>(mTexture);
}
void
TestSfmlCanvas::OnUpdate()
{
clear(sf::Color(64, 196, 196));
draw(*mSprite);
}
void
TestSfmlCanvas::toggleSize()
{
if (mLarge) {
mSprite->setScale(sf::Vector2f(1.2f, 1.2f));
}
else {
mSprite->setScale(sf::Vector2f(0.5f, 0.5f));
}
mLarge = !mLarge;
}
IMPLEMENT_APP(TestApplication);
(and main.h) :-
#pragma once
#include <memory>
#include <SFML/Graphics.hpp>
#include <wx/wx.h>
#include <string>
#include "wxSfmlCanvas.h"
// Our overridden class that does some SFML drawing.
class TestSfmlCanvas : public wxSfmlCanvas
{
public:
TestSfmlCanvas(
wxWindow* Parent,
wxWindowID Id,
wxPoint& Position,
wxSize& Size,
long Style = 0
);
void toggleSize();
protected:
void OnUpdate() override;
private:
sf::Texture mTexture;
std::unique_ptr<sf::Sprite> mSprite;
bool mLarge;
};
// wx Frame to contain the main canvas control. Can have extra controls added to it as desired.
class TestFrame : public wxFrame
{
public :
TestFrame();
protected:
TestSfmlCanvas* mCanvas;
};
// Main wx Application instance.
class TestApplication : public wxApp
{
private :
virtual bool OnInit()
{
// Create the main window
TestFrame* MainFrame = new TestFrame;
MainFrame->Show();
return true;
}
};
(wxSFMLCanvas.h) :-
#pragma once
#include <SFML/Graphics.hpp>
#include <wx/wx.h>
#include <string>
class wxSfmlCanvas : public wxControl, public sf::RenderWindow
{
public:
wxSfmlCanvas(wxWindow* Parent = nullptr,
wxWindowID Id = -1,
//const wxPoint& Position = wxDefaultPosition,
const wxSize& Size = wxDefaultSize,
long Style = 0);
virtual ~wxSfmlCanvas();
protected:
virtual void OnUpdate();
void OnIdle(wxIdleEvent&);
void OnPaint(wxPaintEvent&);
void OnEraseBackground(wxEraseEvent&);
void OnSize(wxSizeEvent&);
DECLARE_EVENT_TABLE()
};
(wxSFMLCanvas.cpp) :-
#include "wxSfmlCanvas.h"
#include <wx/wx.h>
#include <string>
BEGIN_EVENT_TABLE(wxSfmlCanvas, wxControl)
EVT_PAINT(wxSfmlCanvas::OnPaint)
EVT_IDLE(wxSfmlCanvas::OnIdle)
EVT_ERASE_BACKGROUND(wxSfmlCanvas::OnEraseBackground)
EVT_SIZE(wxSfmlCanvas::OnSize)
END_EVENT_TABLE()
#ifdef __WXGTK__
#include <string>
#include <gdk/gdkx.h>
#include <gtk/gtk.h>
#include <wx/gtk/win_gtk.h>
#endif
wxSfmlCanvas::wxSfmlCanvas(wxWindow* Parent,
wxWindowID Id,
const wxPoint& Position,
const wxSize& Size,
long Style) :
wxControl(Parent, Id, Position, Size, Style)
{
#ifdef __WXGTK__
#else
sf::RenderWindow::create(GetHandle());
#endif
}
void wxSfmlCanvas::OnIdle(wxIdleEvent&)
{
// Send a paint message when the control is idle, to ensure maximum framerate
Refresh();
}
wxSfmlCanvas::~wxSfmlCanvas()
{
}
void wxSfmlCanvas::OnUpdate()
{
}
void wxSfmlCanvas::OnEraseBackground(wxEraseEvent&)
{
}
void wxSfmlCanvas::OnSize(wxSizeEvent& args)
{
// Set the size of the sfml rendering window
setSize(sf::Vector2u(args.GetSize().x, args.GetSize().y));
// Also adjust the viewport so that a pixel stays 1-to-1.
setView(sf::View(sf::FloatRect(0, 0, args.GetSize().x, args.GetSize().y)));
}
void wxSfmlCanvas::OnPaint(wxPaintEvent&)
{
// Prepare the control to be repainted
wxPaintDC Dc(this);
// Let the derived class do its specific stuff
OnUpdate();
// Display on screen
display();
}
With this code, I get the following compile errors:
Severity Code Description Project File Line Suppression State Error C4996 '_wgetenv': This function or variable may be unsafe. Consider using _wdupenv_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details. ae D:\wxwidg\include\wx\wxcrt.h 1050
And 100 similar others.
Why? what did I do wrong for this?
wxWidgets is properly built, SFML and wx work fine on their own, but when combined, this error takes place for some reason.
The messages you show are not errors at all, they are static analyser warnings and can be safely ignored, the "unsafe" functions are not used in unsafe way inside wxWidgets.

wxWidgets menu bar doesn't show up

I am trying to create a simple program with a menu using wxWidgets. However, the menu doesn't seem to be appearing properly.
This is my code:
helloworld.hpp:
#include <wx/wxprec.h>
#ifndef WX_PRECOMP
#include <wx/wx.h>
#endif
#include "TextFrame.hpp"
class HelloWorldApp : public wxApp {
public:
virtual bool OnInit();
};
DECLARE_APP(HelloWorldApp)
helloworld.cpp:
#include "helloworld.hpp"
IMPLEMENT_APP(HelloWorldApp)
bool HelloWorldApp::OnInit() {
TextFrame *frame = new TextFrame(_T("Hi"), 200, 200, 800, 600);
frame->CreateStatusBar();
frame->SetStatusText(_T("Hello, World!"));
frame->Show(true);
SetTopWindow(frame);
return true;
}
TextFrame.hpp:
#pragma once
#include <wx/wxprec.h>
#ifndef WX_PREC
#include <wx/wx.h>
#endif
class TextFrame : public wxFrame {
public:
/** Constructor. Creates a new TextFrame */
TextFrame(const wxChar *title, int xpos, int ypos, int width, int height);
private:
wxTextCtrl *m_pTextCtrl;
wxMenuBar *m_pMenuBar;
wxMenu *m_pFileMenu;
wxMenu *m_pHelpMenu;
};
TextFrame.cpp:
#include "TextFrame.hpp"
TextFrame::TextFrame(const wxChar *title, int xpos, int ypos, int width, int height)
: wxFrame((wxFrame *) NULL, -1, title, wxPoint(xpos, ypos), wxSize(width, height))
{
m_pTextCtrl = new wxTextCtrl(this, -1, _T("Type some text..."),
wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE);
m_pMenuBar = new wxMenuBar();
// File Menu
m_pFileMenu = new wxMenu();
m_pFileMenu->Append(wxID_OPEN, _T("&Open"));
m_pFileMenu->Append(wxID_SAVE, _T("&Save"));
m_pFileMenu->AppendSeparator();
m_pFileMenu->Append(wxID_EXIT, _T("&Quit"));
m_pMenuBar->Append(m_pFileMenu, _T("&File"));
// About menu
m_pHelpMenu = new wxMenu();
m_pHelpMenu->Append(wxID_ABOUT, _T("&About"));
m_pMenuBar->Append(m_pHelpMenu, _T("&Help"));
SetMenuBar(m_pMenuBar);
}
This code comes (for the most part) directly from here.
It compiles successfully (using g++ TextFrame.cpp helloworld.cpp `wx-config -cxxflags --libs` -o helloworld), but when I run it I see the default menu, and not the custom one I tried to add.
I tried out the "menu" sample and that works fine, so I think I'm doing something wrong here.
Thank you for your help.

Why do my button class items share the same lambda functions?

I am trying to make my own reusable button class in SFML. This would allow me to create a button and add a callback function to it in order to make the creation of buttons much easier.
Here is my hpp file:
#ifndef Button_hpp
#define Button_hpp
#include <stdio.h>
#include <SFML/Graphics.hpp>
#include "View.hpp"
#include "State.hpp"
#include "Window.hpp"
namespace kge {
class Button: public View{
private:
sf::RectangleShape* _buttonOutline;
sf::RenderWindow* _window;
sf::Clock _clock;
std::string _textString;
sf::Text* _text;
public:
Button(Window*, std::string);
~Button();
virtual void update(float td);
std::function<void(void)> callback;
void setPosition(float x, float y);
};
}
#endif /* Button_hpp */
And here is where I generate the buttons:
_restartButton = new kge::Button(_window, "Restart");
_restartButton->setPosition(getCenterOfScreen().x-((11*fontSize)/2), 300);
_restartButton->callback = ([this](){
State::instance().currentView = new GameView(this->_window);
this->_window->setView(State::instance().currentView);
});
_exitButton = new kge::Button(_window, "Quit");
_exitButton->setPosition(getCenterOfScreen().x-((11*fontSize)/2), 500);
_exitButton->callback = ([this](){
this->_window->close();
});
Finally, I tell the button to update and do it's checks in my window update, button->update(td)
All my buttons seem to all do the action of the last set callback. In this case, my restart button executes my exit code.
Why is this happening and how would I fix it?
Edit
Here is my generation code:
#ifndef GameOver_hpp
#define GameOver_hpp
#include <stdio.h>
#include "View.hpp"
#include "Button.hpp"
#include "GameView.hpp"
#include "State.hpp"
namespace kge{
class View;
};
class GameOver: public kge::View{
private:
sf::Text* _text;
kge::Button* _restartButton;
kge::Button* _exitButton;
void restartFunction(void){
}
public:
GameOver(kge::Window* screen) : View(screen){
int fontSize = 50;
_text = new sf::Text();
_text->setFont(kge::AssetManager::mainBundle().getFontNamed("mainfont"));
_text->setString("Game Over");
_text->setCharacterSize(fontSize);
_text->setPosition(getCenterOfScreen().x-((9*fontSize)/2), 100);
_text->setFillColor(sf::Color(255,0,0));
_restartButton = new kge::Button(_window, "Restart");
_restartButton->setPosition(getCenterOfScreen().x-((11*fontSize)/2), 300);
_exitButton = new kge::Button(_window, "Quit");
_exitButton->setPosition(getCenterOfScreen().x-((11*fontSize)/2), 500);
_restartButton->callback = ([this](){
// State::instance().currentView = new GameView(this->_window);
// this->_window->setView(State::instance().currentView);
puts("Restart");
});
_exitButton->callback = ([this](){
// this->_window->close();
puts("Restart");
});
this->addItemToView(_text);
this->addItemToView(_restartButton);
this->addItemToView(_exitButton);
}
void update(float td){
_restartButton->update(td);
_exitButton->update(td);
}
~GameOver(){
delete _text;
delete _restartButton;
}
};
#endif /* GameOver_hpp */
Note, kge::View is just a custom sf::Drawable class (how I create my own "views")
Edit 2
Button update function:
void Button::update(float td){
if(_clock.getElapsedTime().asMilliseconds() < 400) return;
if(!sf::Mouse::isButtonPressed(sf::Mouse::Left)) return;
if(mouseIsIn(*_buttonOutline, _window)){
callback();
_clock.restart();
}
}
Please note: _clock is an sf::Clock that is stored privately in the button class.
The issue was resolved in chat. To summarize, the mouseIsIn function that #iProgram posted did not check collision correctly, leading to multiple buttons triggering at the same time.
The original function:
bool mouseIsIn(sf::RectangleShape shape, sf::RenderWindow* window){
sf::FloatRect shapeBounds = shape.getGlobalBounds();
sf::Vector2i mousePos = sf::Mouse::getPosition(*window);
sf::FloatRect mouseRect = sf::FloatRect(mousePos.x, mousePos.y, mousePos.x+shapeBounds.width, mousePos.y+shapeBounds.height);
return mouseRect.intersects(shapeBounds);
}
The fixed function:
bool mouseIsIn(sf::RectangleShape shape, sf::RenderWindow* window){
sf::FloatRect shapeBounds = shape.getGlobalBounds();
sf::Vector2i mousePos = sf::Mouse::getPosition(*window);
return shapeBounds.contains(mousePos.x, mousePos.y);
}

std::cerr can't print float variable

I am writing a program that is supposed to operate with matrices and to use OpenGL framework for drawing them. Honestly, it's just for practice. Anyway, I tried to compile it and, of course, it didn't run well. Inserting as many logging as I could, I found out that my std::cerr can't print float values. I really got no idea how that may stop working. I have made some deep researches on my little code like replacing variables with their values, coding external programs using same functions and so on; and found even more unbelievable thing that there's absolutely no reason for this.
Useful details
OS X 10.9.
No bugs regarding to precompilation may occur other than ones caused by #pragma once.
Compiler
Apple LLVM version 6.0 (clang-600.0.57) (based on LLVM 3.5svn).
g++ -std=c++11 -framework OpenGL -framework GLUT
main.cpp
#include <GLUT/glut.h>
#include <cstdlib>
#include "Window.hpp"
Window *black_screen;
void Display () { black_screen->Display (); }
void Reshape (int NEW_WIDTH, int NEW_HEIGHT) { black_screen->Reshape (NEW_WIDTH, NEW_HEIGHT); }
void Keyboard (unsigned char key, int x, int y) { black_screen->Keyboard (key, x, y); }
void Special (int key, int x, int y) { black_screen->Special (key, x, y); }
int main(int argc, char **argv) {
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH);
Window *black_screen = new Window(800, 800);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glutDisplayFunc ( Display );
glutReshapeFunc ( Reshape );
glutKeyboardFunc ( Keyboard );
glutSpecialFunc ( Special );
black_screen->AddMatrix(Matrix(5));
Display();
glutMainLoop();
}
WINDOW.hpp
#pragma once
#include <GLUT/glut.h>
#include <cstdlib>
#include <iostream>
#include <string>
#include "Matrix.hpp"
class Window {
std::vector <Matrix> matrices_;
float WIDTH_, HEIGHT_,
SIZE_X_, SIZE_Y_;
const char *NAME_;
public:
Window (const float WIDTH, const float HEIGHT);
private:
void Type (const float x, const float y, const char *string) const;
public:
void AddMatrix (const Matrix &A);
void Write (const std::string &message);
void Display ();
void Reshape (int NEW_WIDTH, int NEW_HEIGHT);
void Keyboard (unsigned char key, int x, int y);
void Special (int key, int x, int y);
};
WINDOW.cpp
// --- THIS IS CONSTRUCTOR --- --- --- --- ---
Window::Window (const float WIDTH, const float HEIGHT) :
WIDTH_(WIDTH), HEIGHT_(HEIGHT),
SIZE_X_(800), SIZE_Y_(800),
NAME_("MATRIX") {
...
}
// --- THIS IS DISPLAY FUNCTION CALLED FROM MAIN::Display() ---
void Window::Display () {
glLoadIdentity(); Write("glLoadIdentity();");
glClear(GL_COLOR_BUFFER_BIT); Write("glClear(GL_COLOR_BUFFER_BIT);");
glMatrixMode(GL_PROJECTION); Write("glMatrixMode(GL_PROJECTION);");
Write("\tNOW i WILL TRY TO OUTPUT HEIGHT_ :");
std::cerr << HEIGHT_ << std::endl;
glOrtho(0, WIDTH_, 0, HEIGHT_, 1, -1); //Write("glOrtho(0, WIDTH_, 0, HEIGHT_, 1, -1);");
...
}
output
[ glutInitWindowSize(SIZE_X_, SIZE_Y_); :
[ SIZE_X_ 800.000000
[ SIZE_Y_ 800.000000
[ glutCreateWindow(NAME_); :
[ NAME_ MATRIX
[ glLoadIdentity();
[ glClear(GL_COLOR_BUFFER_BIT);
[ glMatrixMode(GL_PROJECTION);
[ NOW i WILL TRY TO OUTPUT HEIGHT_ :
make: *** [run] Segmentation fault: 11
You don't show this in the code posted, but it appears you have two different definitions for black_screen, one global and one inside the main function. The one inside main has been initialized properly, but the global one is a bad pointer. The segmentation fault is the result of undefined behavior from dereferencing the bad pointer.