Tuesday, 29 September 2015

Problem finally solved. SDL TTF now working!

I think my main problem was I was using old version of SDL_TTF(old 1.2 version ) with SDL2.

I got passed the TTF_INIT() and it returned 0 which means that it was initialized ok.
I even checked TTF_WasInit() and that was also ok saying it was already loaded.
But when I tried opening a font with this code:
TTF_Font* fFont = 0;
fFont = TTF_OpenFont("./sample.ttf", 12); //open a fontfile and set fontsize

if(fFont == NULL) //check if fFont is NULL, if so output error message
{ 
  std::cout << "Font: " << fFont << std::endl;
  std::cout << "TTF_OpenFont: " << TTF_GetError() << std::endl;
}
it returned NULL and variable fFont displayed 00000000
and TTF_GetError() was empty (opaque,blank,displayed nothing)

also got NO compile errors and the executable ran correctly, but wouldn't load the font.

The solution for me was:

* Dowloaded the SDL_TTF sources again to have fresh and latest files, newest version that goes with latest SDL2.

* Made a new SDL include and lib folder, copied the correct files to those folders,
just to be sure that it was setup right.
* Added those folders to VC++ include and library directories selection in VS2010C++ project properties.

* Redid the compiler "additional c/c++ linker" again in VS2010C++ project properties now adding all the SDL stuff at the end of the list, making sure the kernel32.lib and all regular systemlibs was at the top of the list.

Then cleaned build, compiled and rebuild, ran the executable and then it worked loading a font and displayed text!

Think the "moral of the story" is: check that your linker is correctly setup AND that you're using the LATEST SDL2 versions of the files for both SDL2 main files and the extension library files....

Now I can finally have TEXT in the game... :) (Spent toooo many hours on this "little" #$*&! problem)

I stumbled upon this link that lead me to solving it:
http://www.gamedev.net/topic/649984-sdl2-ttf-issues-entry-point-not-found-visual-studio/

SDL TTF , another tutorial

http://www.sdltutorials.com/sdl-ttf

Thursday, 24 September 2015

SDL render text issue - not appearing

text not appearing, is it z-indexed behind other layers? compile is fine.
maybe need to make placeholder sprite and then render text to it, and then to screen?
is
SDL_RenderCopy(renderer, Message, NULL, &Message_rect);
placement right in the code?
need to check it out.

EDIT:
Seems the font is not loaded ! Getting errors...
Need to make own renderfunction, only load font one time and reference to it.
..found this need to check it out:
http://www.willusher.io/sdl2%20tutorials/2013/12/18/lesson-6-true-type-fonts-with-sdl_ttf/

*** UPDATE ***
This problem has now been solved, read post: http://olejeek.blogspot.com/2015/09/sdl-ttf-now-working-problem-solved.html

Wednesday, 16 September 2015

Some thoughts about SDL texture and sprite z-index

...and a solution ("painters solution").

I've read and heard that SDL don't have any real z-index when it comes to render image on screen,
the last drawn image/sprite/texture has the highest z-index. That got me thinking of a way to correct it.

In a X,Y,Z graphics environment we can correct the z-index like this:
The bigger the number of y-pos is = the bigger the z-index is
or in other words: z-index = y-pos + spriteHeight;
(In most cases you need to add sprite height to y-pos to get the real y-pos, and your sprites need to be cropped/trimmed from unnecessary transparent height so the bottom of the sprites are accurate)



Some pseudo code to explain solution:
if(object.A.pos.y > object.B.pos.y)
{
  redraw(object.B);
  redraw(object.A);
}
else if(object.A.pos.y < object.B.pos.y)
{
  redraw(object.A);
  redraw(object.B);
}


Final coding (c++):
This is what I ended up doing: basically comparing 2 vectors and redraw textures in right order.
Here's my code, I run it last/at the bottom in my gameloop render function,
but surely this can/should be included to the default render function as a permanent part:
/////////////////////////////////////////////////////////////////////////////////////////////////////
//A little sorter-helper function
bool howToSort(int i, int j) { return i < j; }

/////////////////////////////////////////////////////////////////////////////////////////////////////
//A function to get z-index from object, defined in a header file
//It's made out from a getPosition.getY() function and a class member int m_objHeight
int getZindex() { return getPosition().getY() + m_objHeight; }

/////////////////////////////////////////////////////////////////////////////////////////////////////
//Redraw objects to correct the z-index of all screen objects/sprites/textures
//The parameter is a vector of GameObjects (class that makes up the objects) 
void RedrawObjectZindex(const std::vector<GameObject*> &objects)
{
    //Declare a vector of integers to hold all objects z-indexes
    std::vector<int> v_zindex;
    
    for(int i=0; i < objects.size(); i++)
    { 
        //In my case I omit the background image object, it's always going to have the highest zindex, 
        //(largest height+ypos), so I avoid it. (Its textureID=background)
        //objID() is a function that gets the objects textureID
        if(objects[i]->objID() !="background") 
        {
             //Add each objects z-index to the v_zindex vector
             v_zindex.push_back(objects[i]->getZindex());
        }
    }
 
    //Sort the vector from lowest to highest zindex
    sort( v_zindex.begin(), v_zindex.end(), howToSort );

    //Now we redraw objects in correct order by comparing the sorted z-indexes 
    //with objects ypos+height. By drawing the lowest first (smallest value) and
    //highest last (biggest value), we correct the zindex and "depth" is achieved.
    for(int i=0; i < v_zindex.size(); i++)
    {
        for(int j=0; j < objects.size(); j++)
        {
            if(v_zindex[i] == objects[j]->getZindex())
            {
                 //draw() is a function that draws textures to screen
                 objects[j]->draw();
            }   
        }  
    }
    //Clean up this vector
    v_zindex.clear();
}

Monday, 14 September 2015

Rendering text in SDL2

http://stackoverflow.com/questions/22886500/rendering-text-sdl2

Example 1:

//this opens a font style and sets a size
TTF_Font* Sans = TTF_OpenFont("Sans.ttf", 24); 

//this is the color in rgb format, maxing out all would give 
//you the color white, and it will be your text's color
SDL_Color White = {255, 255, 255};  

//as TTF_RenderText_Solid could only be used on SDL_Surface
//then you have to create the surface first
SDL_Surface* surfaceMessage = TTF_RenderText_Solid(Sans, "put your text here", White); 

//now you can convert it into a texture
SDL_Texture* Message = SDL_CreateTextureFromSurface(renderer, surfaceMessage); 

SDL_Rect Message_rect; //create a rect
Message_rect.x = 0;  //controls the rect's x coordinate
Message_rect.y = 0; // controls the rect's y coordinte
Message_rect.w = 100; // controls the width of the rect
Message_rect.h = 100; // controls the height of the rect

//Mind you that (0,0) is on the top left of the window/screen, 
//think a rect as the text's box, that way it would be very simple to understance

//Now since it's a texture, you have to put RenderCopy in your 
//game loop area, the area where the whole code executes

//you put the renderer's name first, the Message, the crop size
SDL_RenderCopy(renderer, Message, NULL, &Message_rect); 
//(you can ignore this if you don't want to dabble with cropping),
//and the rect which is the size and coordinate of your texture
Example 2:
std::string score_text = "score: " + std::to_string(score);        
SDL_Color textColor = { 255, 255, 255, 0 };
SDL_Surface* textSurface = TTF_RenderText_Solid(font, score_text.c_str(), textColor);
SDL_Texture* text = SDL_CreateTextureFromSurface(renderer, textSurface);
int text_width = textSurface->w;
int text_height = textSurface->h;
SDL_FreeSurface(textSurface);
SDL_Rect renderQuad = { 20, win_height - 30, text_width, text_height };
SDL_RenderCopy(renderer, text, NULL, &renderQuad);
SDL_DestroyTexture(text);

Saturday, 5 September 2015

Learn c++

http://www.learncpp.com

http://www.learncpp.com/cpp-tutorial/18-programs-with-multiple-files/

C++ : Classes

There's several ways to pass variables between classes, but I still haven't found a 100% solution to this.
Sometimes things work, sometimes compiler won't compile usually gives "blahblah a non static member...error" or "blahblah cannot resolve external symbol...error".
Sometimes you just need a variable to be in the global scope...

..using the extern keyword:
http://www.cplusplus.com/forum/general/21368/

//FILE: includes.h
//extern tells the compiler that the variable is defined 
//somewhere else, so it doesn't complain about it being undefined.
extern int count;

//FILE: main.cpp
#include "includes.h"
int count = 4;

//FILE other.cpp
#include "includes.h"
std::cout << count << std::endl;// will output 4

other stuff:
http://www.cplusplus.com/doc/tutorial/classes/

http://www.learncpp.com/cpp-tutorial/82-classes-and-class-members/

http://www.learncpp.com/cpp-tutorial/813-friend-functions-and-classes/

//C++  How to control variables between classes 
//first define your prototype variable and functions (static)
//in a header file:

//example.h

class ScrollingBackground
{
public:
  static bool m_bScroll; 

  static void scrollOn();
  static void scrollOff(); 
}

//Then in the example.cpp file declare a variable to "activate" it
//preferebly in the top section
//example.cpp

bool ScrollingBackground::m_bScroll = true;

void scrollOn()
{
 ScrollingBackground::m_bScroll = true; 
}

void scrollOff()
{
 ScrollingBackground::m_bScroll = false; 
}

//Then use #include "example.h" in any file you'd
//like to use the functions scrollOn and scrollOff
//and you can control the variable m_bScroll
Another example to "share" variables between classes use the "friend" syntax:
class Accumulator
{
private:
  int m_nValue;
public:
  Accumulator() { m_nValue = 0; } 
  void Add(int nValue) { m_nValue += nValue; }
 
  //Make the Reset() function a friend of this class
  friend void Reset(Accumulator &cAccumulator);
}
 
//Reset() is now a friend of the Accumulator class
void Reset(Accumulator &cAccumulator)
{
  //And can access the private data of Accumulator objects
  cAccumulator.m_nValue = 0;
}

Below is another example of how to use static variables in multiple files and classes,
in other words: read/write/update variable between files and classes. "Global" access.
////////////////////////////////////////////////////////////////////
//define prototype variables and functions in the public section of your class Player.h
public:
  static int m_iXPlayer; 
  static int m_iYPlayer;

//their values can be accessed in other files if #include "Player.h" is used
//IMPORTANT! need to be declared at the top in player.cpp file TO BE ACTIVATED
//and important to use syntax: variableType className::variableName = value;
//like below. If not the compiler will give you error: cannot resolve external symbol (blabla@..)
int Player::m_iXPlayer = 0;
int Player::m_iYPlayer = 0;
//they can then be used/updated in Player.cpp 
//and then you can read their value in other files and classes

//one way to access their values in other classes is using them in functions and return their value
//in another file named example.h
#include "player.h"

class example 
{
public:
  int iGetX(){return Player::m_iXPlayer;}
  int iGetY(){return Player::m_iYPlayer;} 
}

//then use iGetX() and iGetY() in your code to get the values of the variables