SDL: draw a half-transparent rectangle - perl

I cannot figure out how to draw a half-transparent red rectangle onto the screen surface.
Here's the code I have so far:
#!/usr/bin/perl
use SDL;
use SDL::Video;
use SDL::Surface;
use SDL::Rect;
# the size of the window box or the screen resolution if fullscreen
my $screen_width = 800;
my $screen_height = 600;
SDL::init(SDL_INIT_VIDEO);
# setting video mode
my $screen_surface = SDL::Video::set_video_mode($screen_width, $screen_height, 32, SDL_ANYFORMAT|SDL_SRCALPHA);
# drawing something somewhere
my $mapped_color = SDL::Video::map_RGBA($screen_surface->format(), 255, 0, 0, 128); #should be half-transparent, I suppose?
SDL::Video::fill_rect($screen_surface,
SDL::Rect->new($screen_width / 4, $screen_height / 4,
$screen_width / 2, $screen_height / 2), $mapped_color);
# update an area on the screen so its visible
SDL::Video::update_rect($screen_surface, 0, 0, $screen_width, $screen_height);
sleep(5); # just to have time to see it
It results in the red opaque rectangle on the black background, which is not what I am trying to achieve.

You cannot use SDL_FillRect for transparency. The function will overwrite the surface with the value color. Think of it as a "memset".
Quote from docs: If the color value contains an alpha value then the destination is simply "filled" with that alpha information, no blending takes place.
Use SDL_BlitSurface to get transparency. First create a texture fill it with color and then blit.
I made a little test case for practice:
#include <SDL.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
SDL_Surface* CreateSurface( int width , int height )
{
uint32_t rmask , gmask , bmask , amask ;
/* SDL interprets each pixel as a 32-bit number, so our masks must depend
on the endianness (byte order) of the machine */
#if SDL_BYTEORDER == SDL_BIG_ENDIAN
rmask = 0xff000000;
gmask = 0x00ff0000;
bmask = 0x0000ff00;
amask = 0x000000ff;
#else
rmask = 0x000000ff;
gmask = 0x0000ff00;
bmask = 0x00ff0000;
amask = 0xff000000;
#endif
SDL_Surface* surface = SDL_CreateRGBSurface( 0 , width , height , 32 , rmask , gmask , bmask , amask ) ;
if( surface == NULL )
{
( void )fprintf(stderr, "CreateRGBSurface failed: %s\n", SDL_GetError() );
exit(1);
}
return surface ;
}
void Quit( void )
{
SDL_Quit() ;
exit(0) ;
}
int main(int argc, char *argv[])
{
( void )argc ;
( void )argv ;
int init = !( SDL_Init( SDL_INIT_EVERYTHING ) );
if( !init )
Quit() ;
SDL_Surface* screen = SDL_SetVideoMode( 800 , 600 , 32 , 0 ) ;
if( !screen )
Quit() ;
int run = true ;
while( run )
{
SDL_Event event ;
while( SDL_PollEvent( &event ) )
{
switch( event.type )
{
case SDL_QUIT:
run = false ;
break;
}
}
SDL_Surface* s = CreateSurface( 300 ,300 ) ;
( void )SDL_FillRect( s , NULL , 0xAA0000FF ) ;
SDL_Rect rect = { 100 , 100 } ;
( void )SDL_BlitSurface( s , NULL , screen , &rect ) ;
rect.x = 200 ;
rect.y = 200 ;
( void )SDL_FillRect( s , NULL , 0x440000FF ) ;
( void )SDL_BlitSurface( s , NULL , screen , &rect ) ;
SDL_FreeSurface( s ) ;
( void )SDL_Flip( screen ) ;
SDL_Delay( 15 ) ;
( void )SDL_FillRect( screen , NULL , 0x00FFFF ) ;
}
Quit() ;
return 0;
}

Related

Why does loop crash and and not print? Unity3D

Given a cubic space, this function searches for the next large empty space, places a marker there, and then quits.
However, the function doesn't even print the check message that exists prior to the loops starting, so i don't know how to debug it. The checking starts at 0,0,0 and spaces outside the voxel are returned as true, so it should default all the first loops and send messages back. The unity.exe process jams and i have to abort it.
Why doesn't it print? What else is wrong with it? Even if it is slow, i should be able to track progress within the loops? why wouldn't it?
function findvoidable() //find void space in voxel volume
{
var step = dist+1;
print("start"); WaitForFixedUpdate(); //this doesnt print
for ( var k : int = 0; k < mesher.PNGpaths.Length ; k+=step/2)
for ( var j = 0; j < mesher.tex.height ; j+=step/2)
for ( var i = 0; i < mesher.tex.width ; i+=step/2){
print("in schema");WaitForFixedUpdate();
if (wst( i , j , k )==false )
if (wst( i+step,j ,k )==false )
if (wst( i-step,j ,k )==false )
if (wst( i ,j+step,k )==false )
if (wst( i ,j-step,k )==false )
if (wst( i ,j ,k+step )==false )
if (wst( i ,j ,k-step )==false )
{
var cnt=0;
for ( var x = i-step; x < i+step ; x+=1)
for ( var y = j-step; y < j+step ; y+=1)
for ( var z = k-step; z < k+step ; z+=1)
{
if ( wst( x , y , z ) == false )
cnt+=1;
}
if ( cnt >= step*step*step-3 )
{
refCube.transform.position=Vector3(i,j,k);
break;break;break;break;break;break;
}
else
{
WaitForFixedUpdate();
refCube.transform.position=Vector3(i,j,k);
}
}
}
}
WaitForFixedUpdate is a Coroutine and is not supposed to be run like a normal method.
Instead, try "yield" statement:
yield WaitForFixedUpdate();
More info: https://docs.unity3d.com/ScriptReference/Coroutine.html

Creating a packet as a string and then extracted its fields in C

I need to implement my own packets to send over UDP. I decided that I would do this by sending a char buffer which has the sequence number, checksum, size, and the data of the packet which is bytes from a file. The string i'm sending separates each field by a semicolon. Then, when I receive the string (which is my packet) I want to extract each felid, use them accordingly (the sequence number, size, and checksum) and write the bytes to a file. So far I have wrote a method to create 100 packets, and I'm trying to extract and write the bytes to a file (I'm not doing it in the receiver yet, first I'm testing the parsing in the sender). For some reason, the bytes written to my file are incorrect and I'm getting "JPEG DATATSTREAM CONTAINS NO IMAGE" error when I try to open it.
struct packetNode{
char packet[1052]; // this is the entire packet data including the header
struct packetNode *next;
};
This is how I'm creating my packets:
//populate initial window of size 100
for(i = 0; i < 100; i++){
memset(&data[0], 0, sizeof(data));
struct packetNode *p; // create packet node
p = (struct packetNode *)malloc(sizeof(struct packetNode));
bytes = fread(data, 1, sizeof(data), fp); // read 1024 bytes from file into data buffer
int b = fwrite(data, 1, bytes, fpNew);
printf("read: %d\n", bytes);
memset(&p->packet[0], 0, sizeof(p->packet));
sprintf(p->packet, "%d;%d;%d;%s", s, 0, numPackets, data); // create packet
//calculate checksum
int check = checksum8(p->packet, sizeof(p->packet));
sprintf(p->packet, "%d;%d;%d;%s", s, check, numPackets, data); //put checksum in packet
s++; //incremenet sequence number
if(i == 0){
head = p;
tail = p;
tail->next = NULL;
}
else{
tail->next = p;
tail = p;
tail->next = NULL;
}
}
fclose(fp);
and this is where I parse and write the bytes to a file:
void test(){
FILE *fpNew = fopen("test.jpg", "w");
struct packetNode *ptr = head;
char *tokens;
int s, c, size;
int i = 0;
char data[1024];
while(ptr != NULL){
memset(&data[0], 0, sizeof(data));
tokens = strtok(ptr->packet,";");
s = atoi(tokens);
tokens = strtok(NULL, ";");
c = atoi(tokens);
tokens = strtok(NULL, ";");
size = atoi(tokens);
tokens = strtok(NULL, ";");
if(tokens != NULL)
strcpy(data, tokens);
printf("sequence: %d, checksum: %d, size: %d\n", s,c,size);
int b = fwrite(data, 1, sizeof(data), fpNew);
ptr = ptr->next;
i++;
}
fclose(fpNew);
}
Since there is transfer of binary data, a JPEG stream, this data cannot be treated as a string. It's better to go all binary. For instance, instead of
sprintf(p->packet, "%d;%d;%d;%s", s, 0, numPackets, data); // create packet
you would do
sprintf(p->packet, "%d;%d;%d;", s, 0, numPackets);
memcpy(&p->packet[strlen(p->packet)], data, bytes);
but this leads to parsing problems: we would need to change this:
tokens = strtok(NULL, ";");
if(tokens != NULL)
strcpy(data, tokens);
to something like this:
tokens += 1 + ( size < 10 ? 1 : size < 100 ? 2 : size < 1000 ? 3 : size < 10000 ? 4 : 5 );
memcpy(data, tokens, sizeof(data));
#Binary Protocol
It's easier to use a binary packet:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#pragma push(pack,1)
typedef struct Packet {
int seq, maxseq, size;
unsigned short cksum;
unsigned char payload[];
} Packet;
#pragma pop(pack)
typedef struct PacketNode{
struct PacketNode * next;
Packet packet;
} PacketNode;
PacketNode * allocPacketNode(int maxPayloadSize) {
void * ptr = malloc(sizeof(PacketNode) + maxPayloadSize); // FIXME: error checking
memset(ptr, 0, sizeof(PacketNode) + maxPayloadSize); // mallocz wouldn't cooperate
return (PacketNode*) ptr;
}
PacketNode * prepare(FILE * fp, int fsize, int chunksize)
{
PacketNode * head = allocPacketNode(chunksize);
PacketNode * pn = head;
int rd, seq = 0;
int maxseq = fsize / chunksize + ( fsize % chunksize ? 1 : 0 );
while ( ( rd = fread(pn->packet.payload, 1, chunksize, fp ) ) > 0 )
{
printf("read %d bytes\n", rd);
pn->packet.seq = seq++;
pn->packet.maxseq = maxseq;
pn->packet.size = rd + sizeof(Packet);
pn->packet.cksum = 0;
pn->packet.cksum = ~checksum(&pn->packet, pn->packet.size);
if ( rd == chunksize )
pn = pn->next = allocPacketNode(chunksize);
}
return head;
}
int checksum(unsigned char * data, int len)
{
int sum = 0, i;
for ( i = 0; i < len; i ++ )
sum += data[i];
if ( sum > 0xffff )
sum = (sum & 0xffff) + (sum>>16);
return sum;
}
void test( PacketNode * ptr ) {
FILE *fpNew = fopen("test.jpg", "w");
while (ptr != NULL)
{
printf("sequence: %d/%d, checksum: %04x, size: %d\n",
ptr->packet.seq,
ptr->packet.maxseq,
ptr->packet.cksum,
ptr->packet.size - sizeof(Packet)
);
int b = fwrite(ptr->packet.payload, ptr->packet.size - sizeof(Packet), 1, fpNew);
ptr = ptr->next;
}
fclose(fpNew);
}
void fatal( const char * msg ) { printf("FATAL: %s\n", msg); exit(1); }
int main(int argc, char** argv)
{
if ( ! argv[1] ) fatal( "missing filename argument" );
FILE * fp = fopen( argv[1], "r" );
if ( ! fp ) fatal( "cannot open file" );
fseek( fp, 0, SEEK_END );
long fsize = ftell(fp);
fseek( fp, 0, SEEK_SET );
printf("Filesize: %d\n", fsize );
test( prepare(fp, fsize, 1024) );
}
The #pragma push(pack,1) changes how the compiler aligns fields of the struct. We want them to be compact, for network transport. Using 1 is byte-aligned. The #pragma pop(pack) restores the previous setting of the pack pragma.
A note on the checksum method
First we calculate the sum of all the bytes in the packet:
int sum = 0, i;
for ( i = 0; i < len; i ++ )
sum += data[i];
Since the packet uses an unsigned short (16 bits, max value 65535 or 0xffff) to store the checksum, we make sure that the result will fit:
if ( sum > 0xffff ) // takes up more than 16 bits.
Getting the low 16 bits of this int is done using sum & 0xffff, masking out everything but the low 16 bits. We could simply return this value, but we would loose the information from higher checksum bits. So, we will add the upper 16 bits to the lower 16 bits. Accessing the higher 16 bits is done by shifting the int to the right 16 bits, like so: sum >> 16. This is the same as sum / 65536, since 65536 = 216 = 1 << 16.
sum = (sum & 0xffff) + (sum>>16); // add low 16 bits and high 16 bits
I should note that network packet checksums are usually computed 2 bytes (or 'octets' as they like to call them there) at a time. For that, the data should be cast to an unsigned short *, and len should be divided by 2. However! len may be odd, so in that case we'll need to take special care of the last byte. For instance, assuming that the maximum packet size is even, and that the len argument is always <= max_packet_size:
unsigned short * in = (unsigned short *) data;
if ( len & 1 ) data[len] = 0; // make sure last byte is 0
len = (len + 1) / 2;
The rest of the checksum method can remain the same, except that it should operate on in instead of data.

cv::matchShapes method implementation giving error

My objective is to find the pattern in the image captured from camera for this I found the cv::matchShapes method of opencv to implement it.
When I have implemented this method it is making the app crash on matchShapes method.Might be I have done something wrong:-
I exactly do not know how to use this method in order to find the match shape in my query image.This is what I tried.
Here is my code:-
- (void)tryingMatchShapes:(cv::Mat)_image _image1:(cv::Mat)_image1
{
std::vector<std::vector<cv::Point> > squares;
cv::Mat pyr, timg, gray0(_image.size(), CV_8U), gray;
int thresh = 50, N = 11;
cv::pyrDown(_image, pyr, cv::Size(_image.cols/2, _image.rows/2));
cv::pyrUp(pyr, timg, _image.size());
std::vector<std::vector<cv::Point> > contours;
for( int c = 0; c < 3; c++ ) {
int ch[] = {c, 0};
mixChannels(&timg, 1, &gray0, 1, ch, 1);
for( int l = 0; l < N; l++ ) {
if( l == 0 ) {
cv::Canny(gray0, gray, 0, thresh, 5);
cv::dilate(gray, gray, cv::Mat(), cv::Point(-1,-1));
}
else {
gray = gray0 >= (l+1)*255/N;
}
cv::findContours(gray, contours, CV_RETR_LIST, CV_CHAIN_APPROX_SIMPLE);
}
}
cv::Mat pyr1, timg1, gray2(_image1.size(), CV_8U), gray1;
cv::pyrDown(_image1, pyr1, cv::Size(_image1.cols/2, _image1.rows/2));
cv::pyrUp(pyr1, timg1, _image1.size());
std::vector<std::vector<cv::Point> > contours1;
for( int c = 0; c < 3; c++ ) {
int ch[] = {c, 0};
mixChannels(&timg1, 1, &gray2, 1, ch, 1);
for( int l = 0; l < N; l++ ) {
if( l == 0 ) {
cv::Canny(gray2, gray1, 0, thresh, 5);
cv::dilate(gray1, gray1, cv::Mat(), cv::Point(-1,-1));
}
else {
gray1 = gray2 >= (l+1)*255/N;
}
cv::findContours(gray1, contours1, CV_RETR_LIST, CV_CHAIN_APPROX_SIMPLE);
}
}
for( size_t i = 0; i < contours.size(); i++ )
{
double value= cv::matchShapes(contours[i], contours1[i], CV_CONTOURS_MATCH_I1, 0);
NSLog(#"%f",value);
}
}
UIImage *testImage = [UIImage imageNamed:#"note_with_marks (1).png"];
[self.imageView setImage:testImage];
cv::Mat forground = [testImage CVMat];
UIImage *testImage2 = [UIImage imageNamed:#"1.png"];
cv::Mat forground2 = [testImage2 CVMat];
[self tryingMatchShapes:forground _image1:forground2];
The app is getting crashed.
Error:-
OpenCV Error: Assertion failed (contour1.checkVector(2) >= 0 && contour2.checkVector(2) >= 0 && (contour1.depth() == CV_32F || contour1.depth() == CV_32S) && contour1.depth() == contour2.depth()) in matchShapes, file /Users/Aziz/Documents/Projects/opencv_sources/trunk/modules/imgproc/src/contours.cpp, line 1705
Please some body help me in implementing this method from coding point of view.
Please I need some coding help.I have already gone through I lot of theoretical concepts.
Thanks in advance!
std::vector<std::vector<cv::Point> > contours1;
You can't apply matchShapes to such type. You can apply it for each (one) contour, not for group (array) of contours. For example:
cv::matchShapes(contours[0], contours1[0], CV_CONTOURS_MATCH_I1, 0);

bitmask enumerations in objective-c or C

I'm trying to draw a line, broken out into segments dependent on values. For example, if there are 5 fields, and all 5 fields were true, then my Line would look like
-----
If say the first and last fields were true, and everything else would be false, then it would be
- -
I thought I could do this with a bit mask of some sort. First of all, I've never done a bit mask before, but I think I've seen them here and there. I was wondering how I could go about this, and use enumerations instead of 1/0 for readability. As far as I can see from my data, I would only need values of either 1 or 0 for the different properties. However, it would be good to know how to have one of the values be a three level or higher enumeration for future reference. Thanks!
Trying to do something like:
enum CodingRegions {
Coding = 0x01,
NonCoding = 0x02
};
enum Substitution {
Synonymous = 0x04,
NonSynonmous = 0x05
};
Then based on the value of the object, I could do
bitmask???? = object.CodingRegion | object.Substitution;
Then later, check the value of the bitmask somehow, and then draw the line accordingly based on what the values are.
Not sure exactly what your requirements are, but here is one way it might be written in C:
#include <stdio.h>
typedef enum MyField_ {
hasWombat = 1 << 0,
hasTrinket = 1 << 1,
hasTinRoof = 1 << 2,
hasThreeWheels = 1 << 3,
myFieldEnd = 1 << 4,
} MyField;
void printMyField(MyField data) {
MyField field = 1;
while (field != myFieldEnd) {
printf("%c", data & field ? '-' : ' ');
field <<= 1;
}
printf("\n");
}
int main() {
MyField data = hasTrinket | hasThreeWheels;
printMyField(data);
data |= hasWombat; // set a field
data &= ~hasTrinket; // clear a field
printMyField(data);
return 0;
}
Not sure this is what you want, but:
// assumed Coding/NonCoding, Synonomous/NonSynonymous are opposites of each other. If not, add more bit fields
enum CodingRegions
{
Coding = 1 << 0
} ;
enum Substitution
{
Synonymous = 1 << 1
}
void PrintBitmask( NSUInteger bitmask )
{
printf( "%s", bitmask & Coding != 0 ? "-" : " " ) ;
printf( "%s", bitmask & Substitution != 0 ? "-" : " " ) ;
printf( "\n" ) ;
}
Your PrintBitmask() could also look like this:
void PrintBitmask( NSUInteger bitmask )
{
printf( "%s", bitmask & Coding != 0 ? "Coding" : "Noncoding" ) ;
printf( "|" ) ;
printf( "%s", bitmask & Substitution != 0 ? "Synonymous-" : "Nonsynonymous" ) ;
printf( "\n" ) ;
}
/* I prefer macros over enums (at least for something this simple) */
#define SPACE 0x0
#define DASH 0x1
/* input fields */
int fields[5] = {DASH,SPACE,SPACE,SPACE,DASH};
/* create bitmask */
for (int i=0; i<5; i++) {
mask |= (fields[i] << i);
}
/* interpret bitmask and print the line */
for (int i=0; i<5; i++) {
if (mask & (fields[i] << i)) {
printf("%c", '-');
} else {
printf("%c", ' ');
}
}

Formatting a (large) number "12345" to "12,345"

Say I have a large number (integer or float) like 12345 and I want it to look like 12,345.
How would I accomplish that?
I'm trying to do this for an iPhone app, so something in Objective-C or C would be nice.
Here is the answer.
NSNumber* number = [NSNumber numberWithDouble:10000000];
NSNumberFormatter *numberFormatter = [[NSNumberFormatter alloc] init];
[numberFormatter setNumberStyle:kCFNumberFormatterDecimalStyle];
[numberFormatter setGroupingSeparator:#","];
NSString* commaString = [numberFormatter stringForObjectValue:number];
[numberFormatter release];
NSLog(#"%# -> %#", number, commaString);
Try using an NSNumberFormatter.
This should allow you to handle this correctly on an iPhone. Make sure you use the 10.4+ style, though. From that page:
"iPhone OS: The v10.0 compatibility mode is not available on iPhone OS—only the 10.4 mode is available."
At least on Mac OS X, you can just use the "'" string formatter with printf(3).
$ man 3 printf
`'' Decimal conversions (d, u, or i) or the integral portion
of a floating point conversion (f or F) should be
grouped and separated by thousands using the non-mone-
tary separator returned by localeconv(3).
as in printf("%'6d",1000000);
Cleaner C code
// write integer value in ASCII into buf of size bufSize, inserting commas at tousands
// character string in buf is terminated by 0.
// return length of character string or bufSize+1 if buf is too small.
size_t int2str( char *buf, size_t bufSize, int val )
{
char *p;
size_t len, neg;
// handle easy case of value 0 first
if( val == 0 )
{
a[0] = '0';
a[1] = '\0';
return 1;
}
// extract sign of value and set val to absolute value
if( val < 0 )
{
val = -val;
neg = 1;
}
else
neg = 0;
// initialize encoding
p = buf + bufSize;
*--p = '\0';
len = 1;
// while the buffer is not yet full
while( len < bufSize )
{
// put front next digit
*--p = '0' + val % 10;
val /= 10;
++len;
// if the value has become 0 we are done
if( val == 0 )
break;
// increment length and if it's a multiple of 3 put front a comma
if( (len % 3) == 0 )
*--p = ',';
}
// if buffer is too small return bufSize +1
if( len == bufSize && (val > 0 || neg == 1) )
return bufSize + 1;
// add negative sign if required
if( neg == 1 )
{
*--p = '-';
++len;
}
// move string to front of buffer if required
if( p != buf )
while( *buf++ = *p++ );
// return encoded string length not including \0
return len-1;
}
I did this for an iPhone game recently. I was using the built-in LCD font, which is a monospaced font. I formatted the numbers, ignoring the commas, then stuck the commas in afterward. (The way calculators do it, where the comma is not considered a character.)
Check out the screenshots at RetroJuJu. Sorry--they aren't full-sized screenshots so you'll have to squint!
Hope that helps you (it's in C) :
char* intToFormat(int a)
{
int nb = 0;
int i = 1;
char* res;
res = (char*)malloc(12*sizeof(char));
// Should be enough to get you in the billions. Get it higher if you need
// to use bigger numbers.
while(a > 0)
{
if( nb > 3 && nb%3 == 0)
res[nb++] = ',';
// Get the code for the '0' char and add it the position of the
// number to add (ex: '0' + 5 = '5')
res[nb] = '0' + a%10;
nb++;
a /= 10;
}
reverse(&res);
return res;
}
There might be a few errors I didn't see (I'm blind when it comes to this...)
It's like an enhanced iToA so maybe it's not the best solution.
Use recursion, Luke:
#include <stdio.h>
#include <stdlib.h>
static int sprint64u( char* buffer, unsigned __int64 x) {
unsigned __int64 quot = x / 1000;
int chars_written;
if ( quot != 0) {
chars_written = sprint64u( buffer, quot);
chars_written += sprintf( buffer + chars_written, ".%03u", ( unsigned int)( x % 1000));
}
else {
chars_written = sprintf( buffer, "%u", ( unsigned int)( x % 1000));
}
return chars_written;
}
int main( void) {
char buffer[ 32];
sprint64u( buffer, 0x100000000ULL);
puts( buffer);
return EXIT_SUCCESS;
}