So I'm debugging some horrible code I slung together and finally widdled my way down to (hopefully) the last error in my scene_manager.cpp but I don't seem to understand why I'm getting it.
Error
|22|undefined reference to `scene_manager::applySurface(int, int, SDL_Surface*, SDL_Surface*)'|
scene_manager.cpp
#include "scene_manager.h"
scene_manager::scene_manager(screen_manager* s){
screen = s;
}
void scene_manager::add_object(object_manager* obj){
if(game_objects.find(obj->get_name()) != game_objects.end()){
game_objects[obj->get_name()] = obj;
}
}
void applySurface(int x, int y, SDL_Surface* source, SDL_Surface* destination){
SDL_Rect offset;
offset.x = x;
offset.y = y;
SDL_BlitSurface(source, NULL, destination, &offset);
}
int scene_manager::render(){
for(iter = game_objects.begin(); iter != game_objects.end();iter++){
applySurface(game_objects.at(iter->first)->get_x(),game_objects.at(iter->first)->get_y(),game_objects.at(iter->first)->get_sprite(),screen->get_screen());
}
if(SDL_Flip(screen->get_screen()) == -1){
return 1;
}
return 0;
}
scene_manager.h
#ifndef SCENE_MANAGER_H
#define SCENE_MANAGER_H
#include "SDL/SDL.h"
#include "SDL/SDL_image.h"
#include "object_manager.h"
#include "screen_manager.h"
#include <map>
#include <string>
class scene_manager{
public:
scene_manager();
scene_manager(screen_manager* s);
void add_object(object_manager* obj);
int render();
private:
std::map<std::string,object_manager*>game_objects;
std::map<std::string,object_manager*>::iterator iter;
screen_manager* screen;
void applySurface(int x, int y, SDL_Surface* source, SDL_Surface* destination);
};
#endif
It seems, this line
void applySurface(int x, int y, SDL_Surface* source, SDL_Surface* destination){
wants to read
void scene_manager::applySurface(int x, int y, SDL_Surface* source, SDL_Surface* destination){
You need the scope resolution operator when you define the applySurfacefunction outside the class.
void scene_manager::applySurface(int x, int y, SDL_Surface* source, SDL_Surface* destination){
//^^^^^^^^^^^^^
Related
I am making a SFML framework, and when I use the function loadImage one time, the image loads correctly with all colors, but if I use it two times for another texture, there is only one sprite rendered and it's all white. I read that you don't want to delete the texture or the sprite or it will be white. But in this code I'm storing all the textures in a vector. Does any one know what is wrong in this function?
FM::Image FM::graphics::loadImage(const char* fileName) {
texturesindex++;
sf::Texture texture;
texture.loadFromFile(fileName);
textures.push_back(texture);
sf::Sprite sprite(textures[texturesindex]);
Image image;
image.sprite = sprite;
return image;
}
Here's all the code:
SFFM.cpp:
#include "SFFM.h"
#include <SFML/Graphics.hpp>
#include <vector>
#include <string>
int backgroundcolor[3] = { 0,0,0};
sf::RenderWindow Window(sf::VideoMode(800, 600), "MyGame");
std::vector<sf::Texture> textures;
int texturesindex = -1;
void FM::window::setWindowOptions(unsigned int Width, unsigned int Height, const char* Title, int FrameLimit) {
Window.setSize(sf::Vector2u(Width, Height));
Window.setFramerateLimit(FrameLimit);
Window.setTitle(Title);
}
void FM::window::setBackgroundColor(int r, int g, int b) {
backgroundcolor[0] = r;
backgroundcolor[1] = g;
backgroundcolor[2] = b;
}
FM::Image FM::graphics::loadImage(const char* fileName) {
texturesindex++;
sf::Texture texture;
texture.loadFromFile(fileName);
textures.push_back(texture);
sf::Sprite sprite(textures[texturesindex]);
Image image;
image.sprite = sprite;
return image;
}
void FM::graphics::drawImage(Image image, int x, int y, int scalex, int scaley, int rotation) {
image.sprite.setPosition(x, -y);
image.sprite.setRotation(rotation);
image.sprite.setScale(sf::Vector2f(scalex, scaley));
Window.draw(image.sprite);
}
void FM::graphics::drawImage(Image image, int x, int y, int scalex, int scaley) {
image.sprite.setPosition(x, -y);
image.sprite.setScale(sf::Vector2f(scalex, scaley));
Window.draw(image.sprite);
}
void FM::graphics::drawImage(Image image, int x, int y) {
image.sprite.setPosition(x, -y);
Window.draw(image.sprite);
}
int main()
{
FM::Start();
while (Window.isOpen())
{
sf::Event event;
while (Window.pollEvent(event))
{
if (event.type == sf::Event::Closed)
Window.close();
else if (event.type == sf::Event::Resized)
{
Window.setView(sf::View(sf::FloatRect(0, 0, event.size.width, event.size.height)));
}
}
Window.clear(sf::Color(backgroundcolor[0], backgroundcolor[1], backgroundcolor[2]));
FM::Update();
Window.display();
}
return 0;
}
SFFM.h:
#pragma once
#include <SFML/Graphics.hpp>
namespace FM
{
void Update();
void Start();
class window {
public:
static void setWindowOptions(unsigned int Width, unsigned int Height, const char * Title, int FrameLimit);
static void setBackgroundColor(int r, int g, int b);
};
class Image {
public:
sf::Sprite sprite;
};
class graphics {
public:
static Image loadImage(const char* fileName);
static void drawImage(Image image, int x, int y, int scalex, int scaley, int rotation);
static void drawImage(Image image, int x, int y, int scalex, int scaley);
static void drawImage(Image image, int x, int y);
};
class Input {
public:
};
};
main.cpp:
#include "SFFM.h"
#include <SFML\Graphics.hpp>
FM::Image Gangster;
FM::Image Block;
int x = 0;
int y = 0;
void FM::Start() {
window::setWindowOptions(1280, 720, "Platformer", 120);
window::setBackgroundColor(0, 127, 255);
Gangster = graphics::loadImage("assets/Gangster.png");
}
void FM::Update() {
graphics::drawImage(Gangster, x, y, 5, 5);
graphics::drawImage(Block, 100, 100, 5, 5);
if (sf::Keyboard::isKeyPressed(sf::Keyboard::W)) {
y += 1;
}
if (sf::Keyboard::isKeyPressed(sf::Keyboard::S)) {
y -= 1;
}
if (sf::Keyboard::isKeyPressed(sf::Keyboard::D)) {
x += 1;
}
if (sf::Keyboard::isKeyPressed(sf::Keyboard::A)) {
x -= 1;
}
}
Here's a screenshot:
TL;DR Solutions, either:
Use a container other than std::vector<sf::Texture> - std::list<sf::Texture> or std::forward_list<sf::Texture>.
Store pointers to textures - std::vector<std::unique_ptr<sf::Texture>>.
Explanation
You store texture objects along with sprites referring them. This is correct because a spite just keeps a reference (a pointer) to its texture. This also implies that the texture address must remain unchanged during the sprite lifetime.
It looks like you did not take into account how std::vector push_back() works. A vector initally allocates some memory, and once there is no place to insert a new item, the vector allocates more memory and copies all inserted items and the new one there. So all the item addresses change.
In your case an item is a texture, its address is changed upon an isertion of another texture, so some sprite "looses" its texture. This usually results in white squares drawn.
This question already has answers here:
What is an undefined reference/unresolved external symbol error and how do I fix it?
(39 answers)
Closed 6 years ago.
I created base Sprite class:
#ifndef SPRITE_H_
#define SPRITE_H_
#include<iostream>
#include<SDL2/SDL.h>
#include<SDL2/SDL_image.h>
class Sprite
{
public:
Sprite(SDL_Texture* texture, int x, int y, int w, int h, SDL_Renderer* p_renderer);
virtual ~Sprite();
SDL_Rect getRect();
SDL_Texture* loadImage(std::string file_path);
void drawSprite();
void setPosition(int x, int y);
float getXpos();
float getYpos();
private:
SDL_Renderer* gRenderer;
SDL_Texture* image;
SDL_Rect rect;
//for position update
float x_pos;
float y_pos;
};
#endif /* SPRITE_H_ */
#include "Sprite.h"
Sprite::Sprite(SDL_Texture* texture, int x, int y, int w, int h, SDL_Renderer* p_renderer)
{
gRenderer = p_renderer;
image = texture;
rect.x = x;
rect.y = y;
rect.w = w;
rect.h = h;
x_pos = x;
y_pos = y;
}
Sprite::~Sprite()
{
SDL_DestroyTexture(image);
}
float Sprite::getXpos()
{
return x_pos;
}
float Sprite::getYpos()
{
return y_pos;
}
SDL_Texture* loadImage(std::string file_path, SDL_Renderer* p_renderer)
{
return IMG_LoadTexture(p_renderer, file_path.c_str());
}
void Sprite::drawSprite()
{
SDL_RenderCopy(gRenderer, image, NULL, &rect);
}
Next I created Bird class that is using Sprite class as a base:
/*
* Bird.h
*
* Created on: 1 maj 2016
* Author: Astral
*/
#ifndef BIRD_H_
#define BIRD_H_
#include "Sprite.h"
class Bird: public Sprite
{
public:
Bird(SDL_Texture* texture, int x, int y, int w, int h, SDL_Renderer* p_renderer, float p_speed, float p_acceleration);
virtual ~Bird();
void updateBird(int x, int y);
void handleInput();
private:
float speed, acceleration;
};
#endif /* BIRD_H_ */
#include "Bird.h"
Bird::Bird(SDL_Texture* texture, int x, int y, int w, int h, SDL_Renderer* p_renderer, float p_speed, float p_acceleration):Sprite(texture, x, y, w, h, p_renderer)
{
speed = p_speed;
acceleration = p_acceleration;
}
Bird::~Bird()
{
}
void Bird::updateBird(int x, int y)
{
Sprite::setPosition(x, y);
}
Now I'm getting error and I have no idea why:
../src/Bird.cpp:18: undefined reference to `Sprite::setPosition(int, int)'
Sprite.cpp
1.
void Sprite::setPosition(int x, int y)
{
x_pos = x;
y_pos = y;
}
2.
SDL_Texture* loadImage(std::string file_path, SDL_Renderer* p_renderer)
↓
SDL_Texture* Sprite::loadImage(std::string file_path)
So I'm basically following a book called SDL Game Development by Shaun Mitchell.
I'm current on page 58, where it tells us how to implement polymorphism.
So far what I have down are:
- Create the main code where we do all our rendering updating etc. (Game.cpp and Game.h)
- Create a Texture manager as a singleton (TextureManager.h and TextureManager.cpp)
- Create a GameObject (GameObject.h and GameObject.cpp)
- Create a Player that inherits GameObject (Player.h and Player.cpp)
So my GameObject class basically has 3 methods: load, draw and update.
Load basically loads an image, and I use my TextureManager to do so.
Draw draws it and update just changes it positions and current frame.
I pass the name of the image which is basically the directory, the renderer and the textureID from the Game class where I call them.
Essentially the problem is that I pass in two different directories into a GameObject
and a Player, but it only loads up the last directory I pass in. As in both GameObject and Player becomes the same image.
So I think the problem lies in Game class, Player class or GameObject class.
I create the objects in Game class, and push them in vector at Game.cpp in init function
Where it says
m_go->load(100, 100, 96, 60, "assets/simba.bmp", "animate",m_pRenderer);
m_player->load(300, 300, 96, 60, "assets/download.bmp", "animate",m_pRenderer);
GameObject.h
#ifndef GAMEOBJECT_H
#define GAMEOBJECT_H
#include <string>
#include <iostream>
#include "SDL_image.h"
#include "TextureManager.h"
class GameObject
{
public:
virtual bool load(int x, int y, int width, int height, std::string name, std::string textureID, SDL_Renderer* pRenderer);
virtual void draw(SDL_Renderer* pRenderer);
virtual void update();
virtual void clean();
protected:
std::string m_textureID;
int m_currentFrame;
int m_currentRow;
int m_x;
int m_y;
int m_width;
int m_height;
};
#endif // GAMEOBJECT_H
GameObject.cpp
#include "GameObject.h"
bool GameObject::load(int x, int y, int width, int height, std::string name, std::string textureID, SDL_Renderer* pRenderer)
{
m_x = x;
m_y = y;
m_width = width;
m_height = height;
m_textureID = textureID;
m_currentRow = 1;
m_currentFrame = 1;
if(!TextureManager::Instance()->load(name, textureID, pRenderer))
{
return false;
}
return true;
}
void GameObject::draw(SDL_Renderer* pRenderer)
{
TextureManager::Instance()->drawFrame(m_textureID, m_x, m_y,m_width, m_height, m_currentRow, m_currentFrame, pRenderer);
}
void GameObject::update()
{
m_x += 1;
m_currentFrame = int(((SDL_GetTicks() / 100) % 6));
}
void GameObject::clean()
{
}
In my Player class, I do the same thing except I use the methods that are already made in GameObject
Player.h
#ifndef PLAYER_H
#define PLAYER_H
#include "GameObject.h"
class Player : public GameObject
{
public:
bool load(int x, int y, int width, int height, std::string name, std::string textureID, SDL_Renderer* pRenderer);
void draw(SDL_Renderer* pRenderer);
void update();
void clean();
};
#endif // PLAYER_H
Player.cpp
#include "Player.h"
bool Player::load(int x, int y, int width, int height, std::string name, std::string textureID, SDL_Renderer* pRenderer)
{
if(!GameObject::load(x, y, width, height, name, textureID, pRenderer))
{
return false;
}
return true;
}
void Player::draw(SDL_Renderer* pRenderer)
{
GameObject::draw(pRenderer);
}
void Player::update()
{
m_currentFrame = int(((SDL_GetTicks() / 100) % 6));
m_x -= 1;
}
void Player::clean()
{
}
This is the part where the images doesn't load the same thing happens in Game.cpp
So I basically created a vector that holds GameObjects, it told me to use it so that I could just for loop through it whenever I want to draw objects
Game.h
#ifndef GAME_H
#define GAME_H
#include <SDL.h>
#include <SDL_image.h>
#include <string.h>
#include <iostream>
#include <vector>
#include "TextureManager.h"
#include "Player.h"
class Game
{
public:
Game() {}
~Game() {}
bool init(const char* title, int xpos, int ypos, int width, int height, int flags);
void render();
void update();
void handleEvents();
void clean();
// a function to access the private running variable
bool running() { return m_bRunning; }
private:
SDL_Window* m_pWindow;
SDL_Renderer* m_pRenderer;
int m_currentFrame;
bool m_bRunning;
GameObject* m_go;
GameObject* m_player;
std::vector<GameObject*> m_gameObjects;
};
#endif
Game.cpp
#include "Game.h"
typedef TextureManager TheTextureManager; // Singleton TextureManager
Game* g_game = 0; // Game Object
bool Game::init(const char* title, int xpos, int ypos, int width,int height, int flags)
{
// attempt to initialize SDL
if(SDL_Init(SDL_INIT_EVERYTHING) == 0)
{
std::cout << "SDL init success\n";
// init the window
m_pWindow = SDL_CreateWindow(title, xpos, ypos,width, height, flags);
if(m_pWindow != 0) // window init success
{
std::cout << "window creation success\n";
m_pRenderer = SDL_CreateRenderer(m_pWindow, -1, 0);
if(m_pRenderer != 0) // renderer init success
{
std::cout << "renderer creation success\n";
SDL_SetRenderDrawColor(m_pRenderer,255,255,255,255);
}
else
{
std::cout << "renderer init fail\n";
return false; // renderer init fail
}
}
else
{
std::cout << "window init fail\n";
return false; // window init fail
}
}
else
{
std::cout << "SDL init fail\n";
return false; // SDL init fail
}
std::cout << "init success\n";
m_go = new GameObject();
m_player = new Player();
m_go->load(100, 100, 96, 60, "assets/simba.bmp", "animate",m_pRenderer);
m_player->load(300, 300, 96, 60, "assets/download.bmp", "animate",m_pRenderer);
m_gameObjects.push_back(m_go);
m_gameObjects.push_back(m_player);
m_bRunning = true; // everything inited successfully, start the main loop
return true;
}
void Game::render()
{
SDL_RenderClear(m_pRenderer); // clear the renderer to the draw color
//m_go.draw(m_pRenderer);
//m_player.draw(m_pRenderer);
for(std::vector<GameObject*>::size_type i = 0; i != m_gameObjects.size(); i++)
{
m_gameObjects[i]->draw(m_pRenderer);
}
SDL_RenderPresent(m_pRenderer); // draw to the screen
}
void Game::clean()
{
std::cout << "cleaning game\n";
SDL_DestroyWindow(m_pWindow);
SDL_DestroyRenderer(m_pRenderer);
SDL_Quit();
}
void Game::handleEvents()
{
SDL_Event event;
if(SDL_PollEvent(&event))
{
switch (event.type)
{
case SDL_QUIT:
m_bRunning = false;
break;
default:
break;
}
}
}
void Game::update()
{
//m_currentFrame = int(((SDL_GetTicks() / 100) % 6));
//m_go.update();
//m_player.update();
for(std::vector<GameObject*>::size_type i = 0; i != m_gameObjects.size(); i++)
{
m_gameObjects[i]->update();
}
}
int main(int argc, char* argv[])
{
g_game = new Game();
g_game->init("Chapter 1", 100, 100, 640, 480, 0);
while(g_game->running())
{
g_game->render();
g_game->handleEvents();
g_game->update();
SDL_Delay(10); // add the delay
}
g_game->clean();
return 0;
}
As you can see at the end of the init function, I have m_go load up simba, and m_player load up download. Even though they move in different directions (GameObject moves to the right and Player moves to the left as you can see in the classes in update method).
My program only loads download for both.
I'm not sure if the TextureManager class is related but I'll post it anyway
TextureManager.h
#ifndef TEXTUREMANAGER_H
#define TEXTUREMANAGER_H
#include <SDL.h>
#include <SDL_image.h>
#include <string.h>
#include <iostream>
#include <map>
class TextureManager
{
public:
bool load(std::string fileName,std::string id,SDL_Renderer* pRenderer);
void draw(std::string id, int x, int y, int width, int height, SDL_Renderer* pRenderer, SDL_RendererFlip flip = SDL_FLIP_NONE);
void drawFrame(std::string id, int x, int y, int width, int height, int currentRow, int currentFrame, SDL_Renderer* pRenderer, SDL_RendererFlip flip = SDL_FLIP_NONE);
std::map <std::string, SDL_Texture*> m_textureMap;
static TextureManager* Instance()
{
if(s_pInstance == 0)
{
s_pInstance = new TextureManager();
return s_pInstance;
}
return s_pInstance;
}
//typedef TextureManager TheTextureManager;
protected:
private:
TextureManager(){}
static TextureManager* s_pInstance;
};
#endif // TEXTUREMANAGER_H
TextureManager.cpp
#include "TextureManager.h"
TextureManager* TextureManager::s_pInstance = 0;
bool TextureManager::load(std::string fileName, std::string id, SDL_Renderer* pRenderer)
{
SDL_Surface* pTempSurface = IMG_Load(fileName.c_str());
if(pTempSurface == 0)
{
return false;
}
SDL_Texture* pTexture =
SDL_CreateTextureFromSurface(pRenderer, pTempSurface);
SDL_FreeSurface(pTempSurface);
// everything went ok, add the texture to our list
if(pTexture != 0)
{
m_textureMap[id] = pTexture;
return true;
}
// reaching here means something went wrong
return false;
}
void TextureManager::draw(std::string id, int x, int y, int width, int height, SDL_Renderer* pRenderer, SDL_RendererFlip flip)
{
SDL_Rect srcRect;
SDL_Rect destRect;
srcRect.x = 0;
srcRect.y = 0;
srcRect.w = destRect.w = width;
srcRect.h = destRect.h = height;
destRect.x = x;
destRect.y = y;
SDL_RenderCopyEx(pRenderer, m_textureMap[id], &srcRect,
&destRect, 0, 0, flip);
}
void TextureManager::drawFrame(std::string id, int x, int y, int width, int height, int currentRow, int currentFrame, SDL_Renderer *pRenderer, SDL_RendererFlip flip)
{
SDL_Rect srcRect;
SDL_Rect destRect;
srcRect.x = width * currentFrame;
srcRect.y = height * (currentRow - 1);
srcRect.w = destRect.w = width;
srcRect.h = destRect.h = height;
destRect.x = x;
destRect.y = y;
SDL_RenderCopyEx(pRenderer, m_textureMap[id], &srcRect,
&destRect, 0, 0, flip);
}
You are using "animate" more than once for the textureID - this needs to be unique
Your Code:
m_go->load(100, 100, 96, 60, "assets/simba.bmp", "animate", m_pRenderer);
m_player->load(300, 300, 96, 60, "assets/download.bmp", "animate", m_pRenderer)
What happens is the texture is loaded but it overwrites the existing texture which has the "animate" key in the map. Make them unique and this should resolve your issue.
I am working on a simple game in C++, with SDL as my API. I put my image bliting functions in a class on a separate document so that it would less messy on my main file. However, when I try to call the functions using the object for the class, my IDE says that I am making an undefined reference to the functions. Here is the main file:
#include "SDL/SDL.h"
#include "SDL/SDL_image.h"
#include "SDL/SDL_ttf.h"
#include "imageBlitingFunctions.h"
#include <iostream>
#include <string>
#include <sstream>
int screenW = 640;
int screenH = 480;
int screenBPP = 32;
SDL_Surface* window = SDL_SetVideoMode(screenW, screenH, screenBPP, SDL_SWSURFACE);
imageBlitingFunctions IBFobject;
SDL_Surface* background1;
SDL_Surface* player1;
int main(int argc, char* args[])
{
SDL_Init(SDL_INIT_EVERYTHING);
TTF_Init();
background1 = IBFobject.loadIMG("background.png");
player1 = IBFobject.loadIMG("swordtest.png");
IBFobject.blitIMG(0, 0, window, background1, 0, 0, 1000, 1000);
IBFobject.blitIMG(0, 0, window, player1, 100, 0, 100, 300);
SDL_FreeSurface(background1);
SDL_FreeSurface(player1);
SDL_Quit();
return 0;
}
Here is the header for the class:
#include "SDL/SDL.h"
#include "SDL/SDL_image.h"
#include "SDL/SDL_ttf.h"
#include <iostream>
#include <string>
#ifndef IMAGEBLITINGFUNCTIONS_H
#define IMAGEBLITINGFUNCTIONS_H
class imageBlitingFunctions
{
public:
SDL_Surface *loadIMG(std::string filename);
void blitIMG(int pX, int pY, SDL_Surface *window, SDL_Surface *image, int cpX, int cpY, int cpH, int cpW);
SDL_Surface *loadText(int red, int blue, int green, std::string fontname, int fontSize, std::string text);
};
#endif // IMAGEBLITINGFUNCTIONS_H
And here is the class:
#include "imageBlitingFunctions.h"
#include "SDL/SDL.h"
#include "SDL/SDL_image.h"
#include "SDL/SDL_ttf.h"
#include <iostream>
#include <string>
SDL_Surface* imageBlitingFunctions::loadIMG(std::string filename)
{
SDL_Surface *img = IMG_Load(filename.c_str());
SDL_Surface *imgOPT = SDL_DisplayFormat(img);
SDL_FreeSurface(img);
return imgOPT;
}
void imageBlitingFunctions::blitIMG(int pX, int pY, SDL_Surface *window, SDL_Surface *image, int cpX, int cpY, int cpH, int cpW)
{
SDL_Rect positionIMG;
positionIMG.x = pX;
positionIMG.y = pY;
SDL_Rect clipP;
clipP.x = cpX;
clipP.y = cpY;
clipP.h = cpH;
clipP.w = cpW;
SDL_BlitSurface(image, &clipP, window, &positionIMG);
SDL_Flip(window);
}
SDL_Surface* imageBlitingFunctions::loadText(int red, int blue, int green, std::string fontname, int fontSize, std::string text)
{
int color1 = red;
int color2 = blue;
int color3 = green;
SDL_Color textColor = {color1, color2, color3};
TTF_Font *font1 = TTF_OpenFont(fontname.c_str(), fontSize);
SDL_Surface *message1 = TTF_RenderText_Solid(font1, text.c_str(), textColor);
return message1;
}
Any help would be appreciated.
An undefined reference to a function means that the linker can't find the function definition. The definition of the function is what you've put in the code "And here is the class:" (maybe you call it imageBlitingFunctions.cpp or something similar?) so the problem is that you're IDE can't find this file.
To solve this problem you need to fix the project configuration.
As far as I can see the code for this class works yet it will not compile and is throwing the error mentioned in the title. Below is the header file.
This is using the SDL standard libraries.
texture2D.h
#ifndef TEXTURE2D_H
#define TEXTURE2D_H
#include <SDL.h>
#include <string>
#include "Commons.h"
using namespace::std;
class Texture2D
{
SDL_Renderer* mRenderer;
SDL_Texture* mTexture;
int mWidth;
int mHeight;
public:
Texture2D(SDL_Renderer* renderer);
~Texture2D();
bool LoadFromFile(string path);
void Free();
void Render(Vector2D newPosition, SDL_RendererFlip flip, double angle = 0.0f);
int GetWidth() { return mWidth; }
int GetHeight() { return mHeight; }
};
#endif
I imagine your definition of Render looks like this
In .cpp
void Texture2D::Render(Vector2D newPosition, SDL_RendererFlip flip, double angle = 0.0f)
{
...
}
When it should be
void Texture2D::Render(Vector2D newPosition, SDL_RendererFlip flip, double angle )
{
...
}
You only supply the default value in the declaration ( normally .h )