One way to render text with SDL is with the extension library SDL_ttf. SDL_ttf allows you to create images from TrueType fonts which use here to create textures from font text.
//Using SDL, SDL_image, SDL_ttf, standard IO, math, and strings
#include <SDL.h>
#include <SDL_image.h>
#include <SDL_ttf.h>
#include <stdio.h>
#include <string>
#include <cmath>
To use SDL_ttf, you have to set up the SDL_ttf extension library just like you would set up SDL_image. Like before, it's just a matter of having the headers files, library files, and binary files in the right place with your compiler configured to use them.
//The window be rendering to
SDL_Window* gWindow = NULL;
//The window renderer
SDL_Renderer* gRenderer = NULL;
//Globally used font
TTF_Font *gFont = NULL;
//Rendered texture
LTexture gTextTexture;
For this and future tutorials, using a global font for our text rendering. In SDL_ttf, the data type for fonts is TTF_Font.
and also have a texture which will be generated from the font.
//Initialize PNG loading
int imgFlags = IMG_INIT_PNG;
if( !( IMG_Init( imgFlags ) & imgFlags ) )
{
printf( "SDL_image could not initialize! SDL_image Error: %s\n", IMG_GetError() );
success = false;
}
//Initialize SDL_ttf
if( TTF_Init() == -1 )
{
printf( "SDL_ttf could not initialize! SDL_ttf Error: %s\n", TTF_GetError() );
success = false;
}
Just like SDL_image, we have to initialize it or the font loading and rendering functions won't work properly.start up SDL_ttf using TTF_init. We can check for errors using TTF_GetError().
void close()
{
//Free loaded images
gTextTexture.free();
//Free global font
TTF_CloseFont( gFont );
gFont = NULL;
//Destroy window
SDL_DestroyRenderer( gRenderer );
SDL_DestroyWindow( gWindow );
gWindow = NULL;
gRenderer = NULL;
//Quit SDL subsystems
TTF_Quit();
IMG_Quit();
SDL_Quit();
}
In our clean up function, we want to free the font using TTF_CloseFont. We also want to quit the SDL_ttf library with TTF_Quit to complete the clean up.
Rabu, 02 Desember 2015
How To Color Keying Using SDL
When rendering multiple images on the screen, having images with transparent backgrounds is usually necessary. Fortunately SDL provides an easy way to do this using color keying.
//Texture wrapper class
class LTexture
{
public:
//Initializes variables
LTexture();
//Deallocates memory
~LTexture();
//Loads image at specified path
bool loadFromFile( std::string path );
//Deallocates texture
void free();
//Renders texture at given point
void render( int x, int y );
//Gets image dimensions
int getWidth();
int getHeight();
private:
//The actual hardware texture
SDL_Texture* mTexture;
//Image dimensions
int mWidth;
int mHeight;
};
Color key the cyan (light blue) colored background and render it on top of this background:
//Texture wrapper class
class LTexture
{
public:
//Initializes variables
LTexture();
//Deallocates memory
~LTexture();
//Loads image at specified path
bool loadFromFile( std::string path );
//Deallocates texture
void free();
//Renders texture at given point
void render( int x, int y );
//Gets image dimensions
int getWidth();
int getHeight();
private:
//The actual hardware texture
SDL_Texture* mTexture;
//Image dimensions
int mWidth;
int mHeight;
};
Color key the cyan (light blue) colored background and render it on top of this background:
(foo.png)
Next, color key the image with SDL_SetColorKey before creating a texture from it. The first argument is the surface to color key, the second argument covers whether to enable color keying, and the last argument is the pixel to color key with.
//The final texture
SDL_Texture* newTexture = NULL;
//Load image at specified path
SDL_Surface* loadedSurface = IMG_Load( path.c_str() );
if( loadedSurface == NULL )
{
printf( "Unable to load image %s! SDL_image Error: %s\n", path.c_str(), IMG_GetError() );
}
else
{
//Color key image
SDL_SetColorKey( loadedSurface, SDL_TRUE, SDL_MapRGB( loadedSurface->format, 0, 0xFF, 0xFF ) );
=Here are the image loading functions in action.=
bool loadMedia()
{
//Loading success flag
bool success = true;
//Load Foo' texture
if( !gFooTexture.loadFromFile( "10_color_keying/foo.png" ) )
{
printf( "Failed to load Foo' texture image!\n" );
success = false;
}
//Load background texture
if( !gBackgroundTexture.loadFromFile( "10_color_keying/background.png" ) )
{
printf( "Failed to load background texture image!\n" );
success = false;
}
return success;
}
=Here are the image loading functions in action.=
void close()
{
//Free loaded images
gFooTexture.free();
gBackgroundTexture.free();
//Destroy window
SDL_DestroyRenderer( gRenderer );
SDL_DestroyWindow( gWindow );
gWindow = NULL;
gRenderer = NULL;
//Quit SDL subsystems
IMG_Quit();
SDL_Quit();
}
How to getting an Image on the Screen using SDL
1. How to getting an Image on the Screen using SDL
Here some global variables.
//The window be rendering to
SDL_Window* gWindow = NULL;
//The surface contained by the window
SDL_Surface* gScreenSurface = NULL;
//The image will load and show on the screen
SDL_Surface* gHelloWorld = NULL;
In the load media function load our image using SDL_LoadBMP. SDL_LoadBMP takes in the path of a bmp file and returns the loaded surface. If the function returns NULL, that means it failed so print to the console an error using SDL_GetError.
bool loadMedia()
{
//Loading success flag
bool success = true;
//Load splash image
gHelloWorld = SDL_LoadBMP( "02_getting_an_image_on_the_screen/hello_world.bmp" );
if( gHelloWorld == NULL )
{
printf( "Unable to load image %s! SDL Error: %s\n", "02_getting_an_image_on_the_screen/hello_world.bmp", SDL_GetError() );
success = false;
}
return success;
}
void close()
{
//Deallocate surface
SDL_FreeSurface( gHelloWorld );
gHelloWorld = NULL;
//Destroy window
SDL_DestroyWindow( gWindow );
gWindow = NULL;
//Quit SDL subsystems
SDL_Quit();
}
Make sure to get into the habit of having your pointers point to NULL when they're not pointing to anything.
int main( int argc, char* args[] )
{
//Start up SDL and create window
if( !init() )
{
printf( "Failed to initialize!\n" );
}
else
{
//Load media
if( !loadMedia() )
{
printf( "Failed to load media!\n" );
}
else
{
//Apply the image
SDL_BlitSurface( gHelloWorld, NULL, gScreenSurface, NULL );
Here some global variables.
//The window be rendering to
SDL_Window* gWindow = NULL;
//The surface contained by the window
SDL_Surface* gScreenSurface = NULL;
//The image will load and show on the screen
SDL_Surface* gHelloWorld = NULL;
In the load media function load our image using SDL_LoadBMP. SDL_LoadBMP takes in the path of a bmp file and returns the loaded surface. If the function returns NULL, that means it failed so print to the console an error using SDL_GetError.
bool loadMedia()
{
//Loading success flag
bool success = true;
//Load splash image
gHelloWorld = SDL_LoadBMP( "02_getting_an_image_on_the_screen/hello_world.bmp" );
if( gHelloWorld == NULL )
{
printf( "Unable to load image %s! SDL Error: %s\n", "02_getting_an_image_on_the_screen/hello_world.bmp", SDL_GetError() );
success = false;
}
return success;
}
void close()
{
//Deallocate surface
SDL_FreeSurface( gHelloWorld );
gHelloWorld = NULL;
//Destroy window
SDL_DestroyWindow( gWindow );
gWindow = NULL;
//Quit SDL subsystems
SDL_Quit();
}
Make sure to get into the habit of having your pointers point to NULL when they're not pointing to anything.
int main( int argc, char* args[] )
{
//Start up SDL and create window
if( !init() )
{
printf( "Failed to initialize!\n" );
}
else
{
//Load media
if( !loadMedia() )
{
printf( "Failed to load media!\n" );
}
else
{
//Apply the image
SDL_BlitSurface( gHelloWorld, NULL, gScreenSurface, NULL );
Stdarg
A function may be called with a varying number of arguments of varying types. The include file <stdarg.h> declares a type va_list and defines three macros for stepping through a list of arguments whose number and types are not known to the called function.
stdarg.h Types
Name : va_list
Description : type for iterating arguments
Macro functions
va_start : Initialize a variable argument list (macro )
va_arg : Retrieve next argument (macro )
va_end : End using variable argument list (macro )
va_copy : Copy variable argument list (macro )
- va_start()
The va_start() macro initializes ap for subsequent use by va_arg() and va_end(), and must be called first.
- va_arg()
The va_arg() macro expands to an expression that has the type and value of the next argument in the call
- va_end()
Each invocation of va_start() must be matched by a corresponding invocation of va_end() in the same function.
-va_copy()
stdarg.h Types
Name : va_list
Description : type for iterating arguments
Macro functions
va_start : Initialize a variable argument list (macro )
va_arg : Retrieve next argument (macro )
va_end : End using variable argument list (macro )
va_copy : Copy variable argument list (macro )
- va_start()
The va_start() macro initializes ap for subsequent use by va_arg() and va_end(), and must be called first.
- va_arg()
The va_arg() macro expands to an expression that has the type and value of the next argument in the call
- va_end()
Each invocation of va_start() must be matched by a corresponding invocation of va_end() in the same function.
-va_copy()
The va_copy() macro copies the (previously initialized) variable argument list src to dest.
-The function "foo" takes a string of format characters and prints out the argument associated with each format character based on the type.
=Example=
#include <stdio.h>
#include <stdarg.h>
void
foo(char *fmt, ...)
{
va_list ap;
int d;
char c, *s;
va_start(ap, fmt);
while (*fmt)
switch (*fmt++) {
case 's': /* string */
s = va_arg(ap, char *);
printf("string %s\n", s);
break;
case 'd': /* int */
d = va_arg(ap, int);
printf("int %d\n", d);
break;
case 'c': /* char */
/* need a cast here since va_arg only
takes fully promoted types */
c = (char) va_arg(ap, int);
printf("char %c\n", c);
break;
}
va_end(ap);
}
-The function "foo" takes a string of format characters and prints out the argument associated with each format character based on the type.
=Example=
#include <stdio.h>
#include <stdarg.h>
void
foo(char *fmt, ...)
{
va_list ap;
int d;
char c, *s;
va_start(ap, fmt);
while (*fmt)
switch (*fmt++) {
case 's': /* string */
s = va_arg(ap, char *);
printf("string %s\n", s);
break;
case 'd': /* int */
d = va_arg(ap, int);
printf("int %d\n", d);
break;
case 'c': /* char */
/* need a cast here since va_arg only
takes fully promoted types */
c = (char) va_arg(ap, int);
printf("char %c\n", c);
break;
}
va_end(ap);
}
Senin, 30 November 2015
File
File is an object on the computer that stores data
There are 2 kinds of file in general:
-Text file (source code, plain text, html files, mosts of configuration files, etc)
-Binary file (mosts audio and video file formats, graphics file formats, compressed files, mosts of office formats, etc)
(-)Type
For files you want to read or write, you need a file pointer:
FILE *fp;
(-)Functions
Reading from or writing to a file in C requires 3 basic steps:
-Open the file.
-Do all the reading or writing.
-Close the file.
-Opening a file:
In order to open a file, use the function fopen(). Use it as:
fp = fopen(filename, mode);
-Reading from or writing to a file:
Once a file has been successfully opened, you can read from it using fscanf() or write to it using fprintf(). These functions work just like scanf() and printf(), except they require an extra first parameter, a FILE * for the file to be read/written.
-Closing a file:
When done with a file, it must be closed using the function fclose().
To finish our example, we'd want to close our input and output files:
fclose(ifp);
fclose(ofp);
=Example=
Write a C program to read name and marks of n number of students from user and store them in a file
#include <stdio.h>
int main(){
char name[50];
int marks,i,n;
printf("Enter number of students: ");
scanf("%d",&n);
FILE *fptr;
fptr=(fopen("C:\\student.txt","w"));
if(fptr==NULL){
printf("Error!");
exit(1);
}
for(i=0;i<n;++i)
{
printf("For student%d\nEnter name: ",i+1);
scanf("%s",name);
printf("Enter marks: ");
scanf("%d",&marks);
fprintf(fptr,"\nName: %s \nMarks=%d \n",name,marks);
}
fclose(fptr);
return 0;
}
There are 2 kinds of file in general:
-Text file (source code, plain text, html files, mosts of configuration files, etc)
-Binary file (mosts audio and video file formats, graphics file formats, compressed files, mosts of office formats, etc)
(-)Type
For files you want to read or write, you need a file pointer:
FILE *fp;
(-)Functions
Reading from or writing to a file in C requires 3 basic steps:
-Open the file.
-Do all the reading or writing.
-Close the file.
-Opening a file:
In order to open a file, use the function fopen(). Use it as:
fp = fopen(filename, mode);
-Reading from or writing to a file:
Once a file has been successfully opened, you can read from it using fscanf() or write to it using fprintf(). These functions work just like scanf() and printf(), except they require an extra first parameter, a FILE * for the file to be read/written.
-Closing a file:
When done with a file, it must be closed using the function fclose().
To finish our example, we'd want to close our input and output files:
fclose(ifp);
fclose(ofp);
=Example=
Write a C program to read name and marks of n number of students from user and store them in a file
#include <stdio.h>
int main(){
char name[50];
int marks,i,n;
printf("Enter number of students: ");
scanf("%d",&n);
FILE *fptr;
fptr=(fopen("C:\\student.txt","w"));
if(fptr==NULL){
printf("Error!");
exit(1);
}
for(i=0;i<n;++i)
{
printf("For student%d\nEnter name: ",i+1);
scanf("%s",name);
printf("Enter marks: ");
scanf("%d",&marks);
fprintf(fptr,"\nName: %s \nMarks=%d \n",name,marks);
}
fclose(fptr);
return 0;
}
Selasa, 24 November 2015
Structures
Structure is the collection of variables of different types under a single name for better handling. For example: You want to store the information about person about his/her name, citizenship number and salary. You can create these information separately but, better approach will be collection of these information under single name because all these information are related to person.
Syntax of structure
struct structure_name
{
data_type member1;
data_type member2;
.
.
data_type memeber;
};
struct person
{
char name[50];
int cit_no;
float salary;
};
This declaration above creates the derived data type struct person.Structures as Function Arguments
You can pass a structure as a function argument in the same way as you pass any other variable or pointer.
#include <stdio.h>
#include <string.h>
struct Books {
char title[50];
char author[50];
char subject[100];
int book_id;
};
/* function declaration */
void printBook( struct Books book );
int main( ) {
struct Books Book1; /* Declare Book1 of type Book */
struct Books Book2; /* Declare Book2 of type Book */
/* book 1 specification */
strcpy( Book1.title, "C Programming");
strcpy( Book1.author, "Nuha Ali");
strcpy( Book1.subject, "C Programming Tutorial");
Book1.book_id = 6495407;
/* book 2 specification */
strcpy( Book2.title, "Telecom Billing");
strcpy( Book2.author, "Zara Ali");
strcpy( Book2.subject, "Telecom Billing Tutorial");
Book2.book_id = 6495700;
/* print Book1 info */
printBook( Book1 );
/* Print Book2 info */
printBook( Book2 );
return 0;
}
void printBook( struct Books book ) {
printf( "Book title : %s\n", book.title);
printf( "Book author : %s\n", book.author);
printf( "Book subject : %s\n", book.subject);
printf( "Book book_id : %d\n", book.book_id);
}
When the above code is compiled and executed, it produces the following result
Book title : C Programming Book author : Nuha Ali Book subject : C Programming Tutorial Book book_id : 6495407 Book title : Telecom Billing Book author : Zara Ali Book subject : Telecom Billing Tutorial Book book_id : 6495700
Example program for array of structures in C
This program is used to store and access “id, name and percentage” for 3 students. Structure array is used in this program to store and display records for many students. You can store “n” number of students record by declaring structure variable as ‘struct student record[n]“, where n can be 1000 or 5000 etc.
#include <stdio.h>
#include <string.h>
struct student
{
int id;
char name[30];
float percentage;
};
int main()
{
int i;
struct student record[2];
// 1st student's record
record[0].id=1;
strcpy(record[0].name, "Raju");
record[0].percentage = 86.5;
// 2nd student's record
record[1].id=2;
strcpy(record[1].name, "Surendren");
record[1].percentage = 90.5;
// 3rd student's record
record[2].id=3;
strcpy(record[2].name, "Thiyagu");
record[2].percentage = 81.5;
for(i=0; i<3; i++)
{
printf(" Records of STUDENT : %d \n", i+1);
printf(" Id is: %d \n", record[i].id);
printf(" Name is: %s \n", record[i].name);
printf(" Percentage is: %f\n\n",record[i].percentage);
}
return 0;
}
Output:
Records of STUDENT : 1 Id is: 1 Name is: Raju Percentage is: 86.500000Records of STUDENT : 2 Id is: 2 Name is: Surendren Percentage is: 90.500000Records of STUDENT : 3 Id is: 3 Name is: Thiyagu Percentage is: 81.500000
Example program for declaring many structure variable in C
In this program, two structure variables “record1″ and “record2″ are declared for same structure and different values are assigned for both structure variables. Separate memory is allocated for both structure variables to store the data.
#include <stdio.h> #include <string.h> struct student { int id; char name[30]; float percentage; }; int main() { int i; struct student record1 = {1, "Raju", 90.5}; struct student record2 = {2, "Mani", 93.5}; printf("Records of STUDENT1: \n"); printf(" Id is: %d \n", record1.id); printf(" Name is: %s \n", record1.name); printf(" Percentage is: %f \n\n", record1.percentage); printf("Records of STUDENT2: \n"); printf(" Id is: %d \n", record2.id); printf(" Name is: %s \n", record2.name); printf(" Percentage is: %f \n\n", record2.percentage); return 0; }
Output:
| Records of STUDENT1: Id is: 1 Name is: Raju Percentage is: 90.500000 Records of STUDENT2: Id is: 2 Name is: Mani Percentage is: 93.500000 |
Pointer And Reference
What is Pointer?
A pointer is a variable whose value is the address of another variable, i.e., direct address of the memory location. Like any variable or constant, you must declare a pointer before using it to store any variable address. The general form of a pointer variable declaration:
When the above code is compiled and executed, it produces the following result
If pointer px is NOT null, then it is pointing to something, however, if the pointer is null, then it is pointing to nothing. The null pointer becomes very useful when you must test the state of a pointer, whether it has a value or not.
To check for a null pointer, you can use an 'if' statement as follows
The declaration of a function that returns a pointer or a reference should seem relatively logical. The above piece of code shows how to basically declare a function that will return a reference or a pointer.
Within the body of the function, the return statement should NOT return a pointer or a reference that has the address in memory of a local variable that was declared within the function, else, as soon as the function exits, all local variables ar destroyed and your pointer or reference will be pointing to some place in memory that you really do not care about. Having a dangling pointer like that is quite inefficient and dangerous outside of your function.
However, within the body of your function, if your pointer or reference has the address in memory of a data type, struct, or class that you dynamically allocated the memory for, using the new operator, then returning said pointer or reference would be reasonable.
type *var-name;
Here, type is the pointer's base type; it must be a valid C++ type and var-name is the name of the pointer variable. The asterisk you used to declare a pointer is the same asterisk that you use for multiplication. However, in this statement the asterisk is being used to designate a variable as a pointer. Following are the valid pointer declaration:
int /* pointer to an integer */double /* pointer to a double */float /* pointer to a float */char /* pointer to a character */
As you know, every variable is a memory location and every memory location has its address defined which can be accessed using ampersand (&) operator, which denotes an address in memory. Consider the following example, which prints the address of the variables defined :
#include <stdio.h>
int main () {
int var1;
char var2[10];
printf("Address of var1 variable: %x\n", &var1 );
printf("Address of var2 variable: %x\n", &var2 );
return 0;
}
When the above code is compiled and executed, it produces the following result
Address of var2 variable: bff5a3f6
What Are Pointer And Reference?
Pointers and reference are essentially variables that hold memory addresses as their values. You learned before about the various different data types such as: int, double, and char. Pointers and references hold the addresses in memory of where you find the data of the various data types that you have declared and assigned. The two mechanisms, pointers and references, have different syntax and different traditional uses.
Declaring Pointer And Reference
When declaring a pointer to an object or data type, you basically follow the same rules of declaring variables and data types that you have been using, only now, to declare a pointer of SOMETYPE, you tack on an asterix * between the data type and its variable.
SOMETYPE* sometype; int* x;
To declare a reference, you do the exact same thing you did to declare a pointer, only this time, rather than using an asterix *, use instead an ampersand &.
SOMETYPE& sometype;
int& x;
As you probably have already learned, spacing in C++ does not matter, so the following pointer declarations are identical:
SOMETYPE* sometype;
SOMETYPE * sometype;
SOMETYPE *sometype;
The following reference declarations are identical as well:
SOMETYPE& sometype;
SOMETYPE & sometype;
SOMETYPE &sometype;
The Null Pointer
Remember how you can assign a character or string to be null? If you don't remember, check out HERE. The null character in a string denotes the end of a string, however, if a pointer were to be assigned to the null pointer, it points to nothing. The null pointer is often denoted by 0 or null. The null pointer is often used in conditions and/or in logical operations.#include <stdio.h>
int main () {
int *ptr = NULL;
printf("The value of ptr is : %x\n", ptr );
return 0;
}
The value of ptr is 0
If pointer px is NOT null, then it is pointing to something, however, if the pointer is null, then it is pointing to nothing. The null pointer becomes very useful when you must test the state of a pointer, whether it has a value or not.
To check for a null pointer, you can use an 'if' statement as follows
if(ptr) /* succeeds if p is not null */ if(!ptr) /* succeeds if p is null */
Returning Pointers and References from Functions
When declaring a function, you must declare it in terms of the type that it will return, for example:int MyFunc(); // returns an int SOMETYPE MyFunc(); // returns a SOMETYPE int* MyFunc(); // returns a pointer to an int SOMETYPE *MyFunc(); // returns a pointer to a SOMETYPE SOMETYPE &MyFunc(); // returns a reference to a SOMETYPE
The declaration of a function that returns a pointer or a reference should seem relatively logical. The above piece of code shows how to basically declare a function that will return a reference or a pointer.
SOMETYPE *MyFunc(int *p)
{
...
...
return p;
}
SOMETYPE &MyFunc(int &r)
{
...
...
return r;
}
Within the body of the function, the return statement should NOT return a pointer or a reference that has the address in memory of a local variable that was declared within the function, else, as soon as the function exits, all local variables ar destroyed and your pointer or reference will be pointing to some place in memory that you really do not care about. Having a dangling pointer like that is quite inefficient and dangerous outside of your function.
However, within the body of your function, if your pointer or reference has the address in memory of a data type, struct, or class that you dynamically allocated the memory for, using the new operator, then returning said pointer or reference would be reasonable.
SOMETYPE *MyFunc() //returning a pointer that has a dynamically
{ //allocated memory address is proper code
int *p = new int[5];
...
...
return p;
}
Returning Pointers to an Array
you can return a pointer to an array by specifying the array's name without an index.If you want to return a single-dimension array from a function, you would have to declare a function returning a pointer as in the following example:
int * myFunction() { . . . }
Langganan:
Postingan (Atom)
