I've set up my project to be split up into two parts - a DLL project which acts as the game engine, and the normal project which compiles to an .exe and relies on the DLL to run.
The issue I've come across, is that if I pass a sprite from the .exe frontend to a function in the DLL that renders sprites, the sprite doesn't render. I've already ensured I setup SFML properly, as when I create a window and render to that window all from the frontend, it works fine, and the same goes for if I put the sprite, texture, and window all in DLL.
I made a very small representation of this and put it up on Github, since I know it's annoying to setup a solution to have multiple projects and link them all together, etc. in Visual Studio:
https://github.com/Bounty556/BrokenDLL Note I am using the latest version of Visual Studio 2019.
The code is as follows:
Main.cpp - in the frontend .exe
#include <Test.h>
#include <SFML/Graphics.hpp>
int main()
{
Test test;
sf::Context context;
sf::Texture texture;
texture.loadFromFile("res/test.png");
sf::Sprite sprite(texture);
test.startWindowAndDraw(sprite);
return 0;
}
Test.h - in the DLL
#pragma once
#include <SFML/Graphics.hpp>
class __declspec(dllexport) Test
{
public:
Test();
void startWindowAndDraw(sf::Sprite& sprite);
private:
sf::RenderWindow m_Window;
};
Test.cpp
#include "Test.h"
Test::Test() :
m_Window(sf::VideoMode(640, 480), "Test", sf::Style::Close)
{
}
void Test::startWindowAndDraw(sf::Sprite& sprite)
{
while (m_Window.isOpen())
{
sf::Event event;
while (m_Window.pollEvent(event))
{
if (event.type == sf::Event::Closed)
m_Window.close();
}
m_Window.clear();
m_Window.draw(sprite);
m_Window.display();
}
}
One thing I noticed is that even though I am creating a window before loading the texture, I still have to create a context, otherwise I get lots of rendering errors. Another thing is, if I don't instantiate Test until after I've loaded the texture, the sprite renders as a blank white rectangle, rather than the image it should be.
It doesn't make sense to me that passing anything from the frontend to the DLL would cause anything weird to happen, since DLLs are essentially part of the program at runtime. If anyone has any insight into this, I would be extremely grateful, as I've been racking my brain on this for quite some time now. Thanks!
Edit:
I forgot some contextual details to go along with this:
OS: Windows 10
Graphics Card: AMD Radeon RX 5700XT
SFML Version: Originally I was using 2.5.1, but upgraded to the latest snapshot release today.
The errors I get in console if I don't create a context before loading the texture are as follows:
An internal OpenGL call failed in RenderWindow.cpp(96).
Expression:
GLEXT_glBindFramebuffer(GLEXT_GL_FRAMEBUFFER, m_defaultFrameBuffer)
Error description:
GL_INVALID_OPERATION
The specified operation is not allowed in the current state.
An internal OpenGL call failed in Texture.cpp(778).
Expression:
glBindTexture(GL_TEXTURE_2D, 0)
Error description:
GL_INVALID_OPERATION
The specified operation is not allowed in the current state.
An internal OpenGL call failed in Texture.cpp(781).
Expression:
glMatrixMode(GL_TEXTURE)
Error description:
GL_INVALID_OPERATION
The specified operation is not allowed in the current state.
An internal OpenGL call failed in Texture.cpp(782).
Expression:
glLoadIdentity()
Error description:
GL_INVALID_OPERATION
The specified operation is not allowed in the current state.
An internal OpenGL call failed in Texture.cpp(785).
Expression:
glMatrixMode(GL_MODELVIEW)
Error description:
GL_INVALID_OPERATION
The specified operation is not allowed in the current state.
An internal OpenGL call failed in RenderTarget.cpp(175).
Expression:
glClearColor(color.r / 255.f, color.g / 255.f, color.b / 255.f, color.a / 255.f)
Error description:
GL_INVALID_OPERATION
The specified operation is not allowed in the current state.
An internal OpenGL call failed in RenderTarget.cpp(176).
Expression:
glClear(GL_COLOR_BUFFER_BIT)
Error description:
GL_INVALID_OPERATION
The specified operation is not allowed in the current state.