May 17, 2015 at 6:58pm UTC
So I was following the Lazyfoo tutorials for SDL and didn't like how he kept everything in one file, so I decided to try and split the classes up, now every method I call from my separate Texture wrapper class is an "undefined symbol".
I should probably add that I don't use C++ much, so this code is probably garbage and I'm probably making a really stupid mistake but I just don't understand why this won't work and am getting very frustrated. So sorry for the stupid question.
I am on Mac and am using Apple LLVM version 6.1.0 as my compiler(not in XCode).
Anyways Here's the code:
JITexture.h
#ifndef JI_TEXTURE
#define JI_TEXTURE
#include <iostream>
#include <string>
//sdl and extension libraries
#include <SDL2/SDL.h>
#include <SDL2_ttf/SDL_ttf.h>
#include <SDL2_image/SDL_image.h>
class JITexture
{
protected:
SDL_Renderer *jRenderer;
SDL_Texture *jTexture;
int jHeight;
int jWidth;
public:
JITexture(SDL_Renderer *renderer);
~JITexture();
bool loadFromFile(std::string path);
void free();
void setColor(Uint8 red, Uint8 green, Uint8 blue);
void setBlendMode(SDL_BlendMode blending);
void setAlpha(Uint8 alpha);
void render(int x, int y, SDL_Rect *clip = NULL, double angle = 0.0, SDL_Point *center = NULL, SDL_RendererFlip = SDL_FLIP_NONE);
int getHeight();
int getWidth();
};
#endif
JITexture.cpp:
#include "JITexture.h"
JITexture::JITexture(SDL_Renderer *renderer)
{
jRenderer = renderer;
jTexture = NULL;
jWidth = 0;
jHeight = 0;
}
JITexture::~JITexture()
{
free();
}
bool JITexture::loadFromFile(std::string path)
{
free();
SDL_Texture *newTexture = NULL;
SDL_Surface *loadedSurface = IMG_Load(path.c_str());
if(loadedSurface == NULL)
{
cout << "Unable to load image!" << std::endl;
}
else
{
SDL_SetColorKey(loadedSurface, SDL_TRUE, SDL_MapRGB(loadedSurface->format, 0, 0xFF, 0xFF));
if(newTexture == NULL)
{
cout << "Unable to create texture!" << std::endl;
}
else
{
jWidth = loadedSurface->w;
jHeight = loadedSurface->h;
}
SDL_FreeSurface(loadedSurface);
}
jTexture = newTexture;
return mTexture!=NULL;
}
void JITexture::free()
{
if(jTexture != NULL)
{
SDL_DestroyTexture(jTexture);
jTexture = NULL;
jWidth = 0;
jHeight = 0;
}
}
void JITexture::setColor(Uint8 red, Uint8 green, Uint8 blue)
{
SDL_SetTextureColorMod(jTexture, red, green, blue);
}
void JITexture::setBlendMode(SDL_BlendMode blending)
{
SDL_SetTextureBlendMode(jTexture, blending);
}
void JITexture::setAlpha(Uint8 alpha)
{
SDL_SetTextureAlphaMod(jTexture, alpha);
}
void JITexture::render(int x, int y, SDL_Rect *clip = NULL, double angle= 0.0, SDL_Point *center = NULL, SDL_RendererFlip = SDL_FLIP_NONE)
{
SDL_Rect renderQuad = {x, y, jWidth, jHeight};
if(clip != NULL)
{
renderQuad.w = clip->w;
renderQuad.h = clip->h;
}
SDL_RenderCopyEx(jRenderer, jTexture, clip, &renderQuad, angle, center, flip);
}
int JITexture::getHeight()
{
return jHeight;
}
int JITexture::getWidth()
{
return jWidth;
}
main.cpp
#include <iostream>
#include <string>
#define SCREEN_WIDTH 640
#define SCREEN_HEIGHT 480
//sdl and extension libraries
#include <SDL2/SDL.h>
#include <SDL2_ttf/SDL_ttf.h>
#include <SDL2_image/SDL_image.h>
#include "JILibrary/JITexture.h"
//global variables
SDL_Window *gWindow = NULL;
SDL_Surface *gScreenSurface = NULL;
SDL_Renderer *gRenderer = NULL;
SDL_Texture *gTexture = NULL;
//textures
JITexture gBackground(gRenderer);
//function declarations
bool init();
bool loadMedia();
void close();
int main()
{
if(!init())
{
std::cout << "Error: Unable to initialize program!" << std::endl;
return 1;
}
if(!loadMedia())
{
std::cout << "Error: Unable to load media!" << std::endl;
}
//variables for gameloop
bool quit = false;
SDL_Event e;
//gameloop
while(!quit)
{
//handle events (keyboard input, mouse input, etc.)
while(SDL_PollEvent(&e) != 0)
{
if(e.type == SDL_QUIT)
{
quit = true;
}
}
//prep renderer by clearing
SDL_SetRenderDrawColor(gRenderer, 0xFF, 0xFF, 0xFF, 0xFF);
SDL_RenderClear(gRenderer);
//call for rendering of textures here
gBackground.render(0, 0);
//initiate rendering
SDL_RenderPresent(gRenderer);
}
close();
return 0;
}
bool init()
{
bool success = true;
if(SDL_Init(SDL_INIT_VIDEO) < 0)
{
std::cout << "Error: Unable to Initialize SDL Video!" << std::endl;
success = false;
}
else
{
gWindow = SDL_CreateWindow("Senior Dash", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, SCREEN_WIDTH, SCREEN_HEIGHT, SDL_WINDOW_SHOWN);
if(gWindow == NULL)
{
std::cout << "Error: Unable to create SDL_Window!" << std::endl;
success = false;
}
else
{
gRenderer = SDL_CreateRenderer(gWindow, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
if(gRenderer == NULL)
{
std::cout << "Error: Unable to create SDL_Renderer!" << std::endl;
success = false;
}
else
{
SDL_SetRenderDrawColor(gRenderer, 0xFF, 0xFF, 0xFF, 0xFF);
int imgFlags = IMG_INIT_PNG;
if(!(IMG_Init(imgFlags) & imgFlags))
{
std::cout << "Error: Unable to initialize SDL_Image!" << std::endl;
success = false;
}
if(TTF_Init() == -1)
{
std::cout << "Error: Unable to initialize SDL_TTF!" << std::endl;
success = false;
}
}
}
}
return success;
}
bool loadMedia()
{
bool success = true;
gBackground.loadFromFile("Media/background.png");
return success;
}
void close()
{
SDL_DestroyRenderer(gRenderer);
gRenderer = NULL;
SDL_DestroyWindow(gWindow);
gWindow = NULL;
TTF_Quit();
IMG_Quit();
SDL_Quit();
}
Linker Error:
Undefined symbols for architecture x86_64:
"JITexture::loadFromFile(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >)", referenced from:
loadMedia() in main-bab0fa.o
"JITexture::render(int, int, SDL_Rect*, double, SDL_Point*, SDL_RendererFlip)", referenced from:
_main in main-bab0fa.o
"JITexture::JITexture(SDL_Renderer*)", referenced from:
___cxx_global_var_init in main-bab0fa.o
"JITexture::~JITexture()", referenced from:
___cxx_global_var_init in main-bab0fa.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
Last edited on May 17, 2015 at 7:05pm UTC