I'm very new to C++ and SDL and I am trying to create a thread that constantly updates the screen but the I keep getting the following errors:
'std::invoke no matching overloaded function found'
and
'Failed to specialize function template 'unknown-type std::invoke(Callable &&,_Types&&...)''
main.cpp
int main(int argc, char **argv) {
using namespace std::placeholders;
bool gameover = false;
int test;
std::string filepath = getResourcePath("Lesson1");
if (SDL_Init(SDL_INIT_EVERYTHING) != 0) { // Intializes SDL functionality
std::cout << "Could not start SDL" << std::endl;
std::cin >> test;
return 1;
}
else {
std::cout << "SDL started successfully!" << std::endl;
}
viewWindow window; // Class representing the window in which the program is run.
SDL_Renderer *render = window.render(); // Pointer to the renderer used to draw images to the window.
if (render == nullptr) {
std::cout << "There was an error creating the renderer" << std::endl << SDL_GetError() << std::endl;
std::cin >> test;
return 1;
}
SDL_Surface *emptySurface = window.blankSurface(); // Temp surface to draw background to
if (emptySurface == nullptr) {
std::cout << "Unable to create a blank surface " << std::endl << SDL_GetError() << std::endl;;
std::cin >> test;
return 1;
}
surfaces background;
background.filename = "grass.bmp";
SDL_Surface *backgroundSurface = background.loadSurface(filepath);
if (backgroundSurface == nullptr) {
std::cout << "Unable to create background surface" << std::endl << SDL_GetError() << std::endl;
std::cin >> test;
return 1;
}
SDL_Rect backgroundRect;
SDL_Texture *backTexture = background.blitBack(render, backgroundRect, backgroundSurface, emptySurface);
player player;
SDL_Rect playerRect;
playerRect.x = 320;
playerRect.y = 240;
playerRect.h = 16;
playerRect.w = 16;
SDL_Texture *playerTexture = player.createPlayerTexture(render, filepath);
if (playerTexture == nullptr) {
std::cout << "Could not load player texture" << std::endl << SDL_GetError() << std::endl;
std::cin >> test;
return 1;
}
while (!gameover) {
std::thread t((&viewWindow::refreshWindow, render, playerRect, backTexture, playerTexture));
playerRect.x = player.moveX(playerRect);
playerRect.y = player.moveY(playerRect);
t.join();
}
return 0;
}
viewWindow.h
#pragma once
#ifndef VIEWINDOW_H
#define VIEWWINDOW_H
#include "SDL.h"
class viewWindow // Class representing the window.
{
private:
char winName[45] = "Game Test";
int winWidth = 640;
int winHeight = 480;
int xPos = 960;
int yPos = 540;
public:
SDL_Window *view(); // Intializing funtions for creating the window and renderer.
SDL_Renderer *render();
SDL_Surface *blankSurface();
void refreshWindow(SDL_Renderer *renderer, SDL_Rect &playerRect, SDL_Texture *backtex, SDL_Texture *playertex);
};
#endif
viewWindow.cpp
#include "viewWindow.h"
#include <string>
#include "SDL.h"
SDL_Window *viewWindow::view()
{
SDL_Window *createdwindow = SDL_CreateWindow(winName, xPos, yPos, winWidth, winHeight, SDL_WINDOW_SHOWN);
return createdwindow;
}
SDL_Renderer *viewWindow::render() {
SDL_Renderer *render = SDL_CreateRenderer(view(), -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
return render;
}
SDL_Surface *viewWindow::blankSurface() {
SDL_Surface *blacksurface = SDL_CreateRGBSurface(0, winWidth, winHeight, 32, 0, 0, 0, 0);
return blacksurface;
}
void viewWindow::refreshWindow(SDL_Renderer *renderer, SDL_Rect &playerRect, SDL_Texture *backtex, SDL_Texture *playertex) {
while (true) {
SDL_RenderClear(renderer);
SDL_RenderCopy(renderer, backtex, NULL, NULL);
SDL_RenderCopy(renderer, playertex, NULL, &playerRect);
SDL_RenderPresent(renderer);
}
}
Method refreshWindow
is not static
. std::invoke
requires the object instance of viewWindow
class to call this method. You should pass it as a second parameter into the thread
constructor:
std::thread t(&viewWindow::refreshWindow, window, render, std::ref(playerRect), backTexture, playerTexture);
Instead of function pointer you could use lambda function:
std::thread t([&](viewWindow* view){ view->refreshWindow(render, playerRect, backTexture, playerTexture); }, &window);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With