SDL 1.2 to SDL 2.0 - rotozoomsurface

Hi! So I'm rewriting this piece of code to SDL 2.0. I think I'm doing okay except for the part with rotozoomsurface. Since I've got rid of all the surfaces, how am I supposed to implement rotation here? Take a look:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269


#include <SDL2/SDL.h>
#include <SDL2/SDL_image.h>
#include <unistd.h>
#include <math.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <string.h>
#include <time.h>
#include <sys/time.h>
#include "SDL_rotozoom.h"
#include "sensor.c"


#define DT 0.2         	// [s/loop] loop period.  0.2  = 200ms
#define AA 0.97         // complementary filter constant

#define A_GAIN 0.0573   // [deg/LSB]
#define G_GAIN 0.070    // [deg/s/LSB]
#define RAD_TO_DEG 57.29578
#define M_PI 3.14159265358979323846

#define DISPLAY_WIDTH 1024
#define DISPLAY_HEIGHT 768


int graphics(float carRoll, float carPitch);
int startSDL();
        //SDL_Surface* screen = NULL;
        SDL_Texture* inclinometerJeepFront = NULL;
        SDL_Texture* inclinometerJeepSide = NULL;
        SDL_Texture* inclinometerOverlay = NULL;
        SDL_Texture* compatibleInclinometerJeepFront = NULL;
        SDL_Texture* compatibleInclinometerJeepSide = NULL;
        SDL_Texture* compatibleInclinometerOverlay = NULL;
        SDL_Texture* rotationInclinometerJeepFront = NULL;
        SDL_Texture* rotationInclinometerJeepSide = NULL;
		SDL_Rect inclinometerJeepOverlayPosition;
        SDL_Rect inclinometerJeepFrontPosition;
        SDL_Rect inclinometerJeepSidePosition;

	//SDL_VideoInfo* videoInfo;

void  INThandler(int sig)
{
        SDL_FreeSurface(screen);
        SDL_Quit();
        signal(sig, SIG_IGN);
        exit(0);
}

int mymillis()
{
	struct timeval tv;
	gettimeofday(&tv, NULL);
	return (tv.tv_sec) * 1000 + (tv.tv_usec)/1000;
}

int timeval_subtract(struct timeval *result, struct timeval *t2, struct timeval *t1)
{
    long int diff = (t2->tv_usec + 1000000 * t2->tv_sec) - (t1->tv_usec + 1000000 * t1->tv_sec);
    result->tv_sec = diff / 1000000;
    result->tv_usec = diff % 1000000;
    return (diff<0);
}

int main(int argc, char *argv[])
{

	float rate_gyr_y = 0.0;   // [deg/s]
	float rate_gyr_x = 0.0;    // [deg/s]
	float rate_gyr_z = 0.0;     // [deg/s]

	int  acc_raw[3];
	int  mag_raw[3];
	int  gyr_raw[3];



	float gyroXangle = 0.0;
	float gyroYangle = 0.0;
	float gyroZangle = 0.0;
	float AccYangle = 0.0;
	float AccXangle = 0.0;
	float CFangleX = 0.0;
	float CFangleY = 0.0;

	int startInt  = mymillis();
	struct  timeval tvBegin, tvEnd,tvDiff;


        signal(SIGINT, INThandler);

	enableIMU();

	gettimeofday(&tvBegin, NULL);

        if(argc <=1)
                startSDL();
        else if (strcmp(argv[1],"nosdl")!= 0)
                startSDL();

	while(1)
	{
	startInt = mymillis();


	//read ACC and GYR data
	readACC(acc_raw);
	readGYR(gyr_raw);

	//Convert Gyro raw to degrees per second
	rate_gyr_x = (float) gyr_raw[0] * G_GAIN;
	rate_gyr_y = (float) gyr_raw[1]  * G_GAIN;
	rate_gyr_z = (float) gyr_raw[2]  * G_GAIN;



	//Calculate the angles from the gyro
	gyroXangle+=rate_gyr_x*DT;
	gyroYangle+=rate_gyr_y*DT;
	gyroZangle+=rate_gyr_z*DT;




	//Convert Accelerometer values to degrees
	AccXangle = (float) (atan2(acc_raw[1],acc_raw[2])+M_PI)*RAD_TO_DEG;
	AccYangle = (float) (atan2(acc_raw[2],acc_raw[0])+M_PI)*RAD_TO_DEG;



        //Change the rotation value of the accelerometer to -/+ 180 and move the Y axis '0' point to up.
        //Two different pieces of code are used depending on how your IMU is mounted.
        //If IMU is upside down
        /*
        if (AccXangle >180)
                AccXangle -= (float)360.0;

        AccYangle-=90;
        if (AccYangle >180)
                AccYangle -= (float)360.0;
        */

        //If IMU is up the correct way, use these lines
        AccXangle -= (float)180.0;
        if (AccYangle > 90)
                AccYangle -= (float)270;
        else
                AccYangle += (float)90;




	//Complementary filter used to combine the accelerometer and gyro values.
	CFangleX=AA*(CFangleX+rate_gyr_x*DT) +(1 - AA) * AccXangle;
	CFangleY=AA*(CFangleY+rate_gyr_y*DT) +(1 - AA) * AccYangle;


	printf ("   GyroX  %7.3f \t AccXangle \e[m %7.3f \t \033[22;31mCFangleX %7.3f\033[0m\t GyroY  %7.3f \t AccYangle %7.3f \t \033[22;36mCFangleY %7.3f\t\033[0m\n",gyroXangle,AccXangle,CFangleX,gyroYangle,AccYangle,CFangleY);


        if(argc <=1)
                graphics(CFangleX,CFangleY);
        else if (strcmp(argv[1],"nosdl")!= 0)
                graphics(CFangleX,CFangleY);


	//Each loop should be at least 20ms.
        while(mymillis() - startInt < (DT*1000))
        {
            usleep(100);
        }

	printf("Loop Time %d\t", mymillis()- startInt);
    }
}

int startSDL()
{
	//fb1 = small TFT.   fb0 = HDMI/RCA output
        putenv("SDL_FBDEV=/dev/fb0");


	//Initialize  SDL and disable mouse
        SDL_Init(SDL_INIT_VIDEO);
        SDL_ShowCursor(SDL_DISABLE);

	//Get information about the current video device.  E.g. resolution and bits per pixal
       // videoInfo = SDL_GetVideoInfo ();

	//Setup a Video mode.
        SDL_Window *screen = SDL_CreateWindow("Window", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 1024, 768, SDL_WINDOW_OPENGL);
		SDL_Renderer *renderer = SDL_CreateRenderer(screen, -1, 0);

	//Load image.
	compatibleInclinometerJeepFront =  IMG_LoadTexture(renderer, "inclinometerJeepFront.png");
        if (compatibleInclinometerJeepFront == NULL){
        printf("error loading JeepFront image\n");
                        SDL_Quit();
                        exit(1);
                }
	//Load image.
	compatibleInclinometerJeepSide =  IMG_LoadTexture(renderer, "inclinometerJeepSide.png");
                if (compatibleInclinometerJeepSide == NULL){
                         printf("error loading JeepSide image\n");
                        SDL_Quit();
                        exit(1);
                }
	//Load image.
        compatibleInclinometerOverlay =  IMG_LoadTexture(renderer, "inclinometerOverlay.png");
                if (compatibleInclinometerOverlay == NULL){
                         printf("error loading Overlay image\n");
                        SDL_Quit();
                        exit(1);
                }

	//Position the overlay in the middle of the screen.   screen heigth minus the height of the overlay image.
        inclinometerJeepOverlayPosition.y = (DISPLAY_HEIGHT/2)-(compatibleInclinometerOverlay->h/2);
}

int graphics(float carRoll, float carPitch)
{

	//Set all pixals to black to clear the last image.
        SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
		SDL_RenderClear(renderer);
		
	//Position of both jeep images.
        inclinometerJeepFrontPosition.x = 30;
        inclinometerJeepFrontPosition.y = (DISPLAY_HEIGHT/2)-(compatibleInclinometerJeepFront->h/2);
        inclinometerJeepSidePosition.x = 262;
        inclinometerJeepSidePosition.y = (DISPLAY_HEIGHT/2)-(compatibleInclinometerJeepFront->h/2);


	//Rotate the images based on pitch and roll.
        rotationInclinometerJeepSide = rotozoomSurface(compatibleInclinometerJeepSide, carPitch, 1.0, 0.0);
        rotationInclinometerJeepFront = rotozoomSurface(compatibleInclinometerJeepFront, carRoll, 1.0, 0.0);

	//Recenter pivot point.
		inclinometerJeepFrontPosition.x -= rotationInclinometerJeepFront->w/2-compatibleInclinometerJeepFront->w/2;
        inclinometerJeepFrontPosition.y -= rotationInclinometerJeepFront->h/2-compatibleInclinometerJeepFront->h/2;
        inclinometerJeepSidePosition.x -= rotationInclinometerJeepSide->w/2-compatibleInclinometerJeepSide->w/2;
        inclinometerJeepSidePosition.y -= rotationInclinometerJeepSide->h/2-compatibleInclinometerJeepSide->h/2;

	//Blit the three iamges to the surface.
	/*SDL_BlitSurface( compatibleInclinometerOverlay, NULL, screen, &inclinometerJeepOverlayPosition);
        SDL_BlitSurface( rotationInclinometerJeepFront, NULL, screen, &inclinometerJeepFrontPosition);
        SDL_BlitSurface( rotationInclinometerJeepSide, NULL, screen, &inclinometerJeepSidePosition);*/
		
	SDL_RenderCopy(renderer, compatibleInclinometerOverlay, NULL, inclinometerJeepOverlayPosition);
	SDL_RenderCopy(rednerer, compatibleInclinometerJeepFront, NULL, inclinometerJeepFrontPosition);
	SDL_RenderCopy(renderer, compatibleInclinometerJeepSide, NULL, inclinometerJeepSidePosition);

	//Free surfaces.
	
		SDL_RenderPresent(renderer);
		
        /*SDL_FreeSurface(screen);
        SDL_FreeSurface(rotationInclinometerJeepFront);
        SDL_FreeSurface(rotationInclinometerJeepSide);*/
        return 0;

}

If you want to use rotozoom you should load the image as a surface that you can use rotozoom on. When you have got the rotated surface you can turn it into a texture using SDL_CreateTextureFromSurface.

https://wiki.libsdl.org/SDL_CreateTextureFromSurface

Another option is to let SDL rotate the surface on the fly when it is drawn on the screen. I have never tested it myself but I think you can use the SDL_RenderCopyEx function to do it, because it has a parameter named angle.

https://wiki.libsdl.org/SDL_RenderCopyEx
Last edited on
Topic archived. No new replies allowed.