Having trouble initializing an SDL_Surface - c++

I'm trying to set up something in SDL [in C++] where I can draw a one pixel big rectangle. I've got everything in my code working except my second SDL_Surface called rectangle. I'm having trouble initializing it. Here's the line where I try to initialize it:
rectangle = SDL_Surface(SDL_DOUBLEBUF | SDL_HWACCEL |
SDL_SRCALPHA | SDL_HWSURFACE,
screen->format, 1, 1, 16, NULL, clip_rect, 1);
Thank you for taking the time to read this and any answers you might choose to give.

I think that the main problem you are having is that there is no SDL_Surface function. To create a new surface, use SDL_CreateRGBSurface. Be sure to call SDL_FreeSurface on the returned surface after you are done with it or you will leak memory.
Additionally, I am not sure why you are creating a surface for the rectangle. A cleaner way of drawing a solid-color rectangle is SDL_FillRect without creating a new surface.

Related

Speeding up drawing bitmap magnification within second bitmap with blend

The following code stretches a bitmap, blends it with an existing background, maintains transparent area of primary graphic and then displays the blend within a window (imgScreen). This works fine when the level of stretch is not large or when it is actually shrinking the initial bitmap. However when stretching the graphic it is very slow.
I have limited experience with C++ and this kind of graphics so perhaps there is another more efficient way to do this. The primary bitmap to be sized is always square. Any ideas are much appreciated..!
I was going to try not displaying clipping area but from tests it seems the initial stretch is causing the slowdown... Also having trouble seeing how to calculate non clipped area... Drawing to controls seems a waste but seems only way to use built in functions like stretchdraw and the alpha draw option.
std::auto_ptr<Graphics::TBitmap> bmap(new Graphics::TBitmap);
std::auto_ptr<Graphics::TBitmap> bmap1(new Graphics::TBitmap);
int s = newsize;
TRect sR = Rect(X,Y,X+s,Y+s);
TRect tR = Rect(0,0,s,s);
bmap->SetSize(s,s);
bmap->Canvas->StretchDraw(Rect(0, 0, s, s), Form1->Image4->Picture-
>Bitmap); // scale
bmap1->SetSize(s,s);
bmap1->Canvas->CopyRect(tR, Form1->imgScreen->Canvas, sR); //background
bmap1->Canvas->Draw(0,0,bmap.get()); // combine
Form1->imgTemp->Picture->Assign(bmap1.get());
Form1->imgScreen->Canvas->Draw(X,Y, Form1->imgTemp->Picture->Bitmap,
alpha);
Displays correctly but as graphic gets larger draw rate slows down quickly...

Rendering to a CCRenderTexture not working

I'm trying to use CCRenderTexture to create a heightmap to use with the Terrain class. I don't know if this is the best way to do it, I'm a newb to both opengl and cocos2d-x, so please bear with me.
auto* renderTexHeightMap = CCRenderTexture::create(width, height);
renderTexHeightMap->begin();
glRasterPos2i(0, 0);
glDrawPixels(width, height, GL_RGB, GL_FLOAT, pixelBuffer);
renderTexHeightMap->end();
renderTexHeightMap->saveToFile("heightmap.jpg", false);
I know that pixelBuffer contains the data that I want (greyscale pixel data), but whenever I call CCRenderTexture::saveToFile all I get is a black picture. What am I missing?
rendertexture will delay one frame to render ,so you need to saveToFile at next frame,my english not good ,do you anderstand?
you can use DelayTime to do it or another way
my way: my code type is lua
local function save()
renderTexture:saveToFile("heightmap.jpg",false)
end
local callfunc = cc.CallFunc:create(save)
local dela = cc.DelayTime:create(0.01)
local seq = cc.Sequence:create(dela,callfunc)
node:runAction(seq)

Sprite::createWithTexture with Rect not working as expected

I'm trying to build a sprite from an image. Using Image and Texture2D class and then later creating a sprite from the texture2D.
The image I am loading is 512x512 and I expected both versions of the createWithTexture to behave the same but they don't. Here the code:
Image* image = new Image();
image->initWithImageFile(fileName);
Texture2D* texture = new Texture2D();
texture->initWithImage(image);
//If used this way everything works as expected
Sprite* spr= Sprite::createWithTexture(texture);
//If used with a Rect weird result occurrs.
Sprite* spr= Sprite::createWithTexture(texture,Rect(0,0,512,512));
spr->setAnchorPoint(Vec2(0,0));
spr->setPosition(Vec2(0,0));
spr->setScale(1.0f,1.0f);
this->addChild(spr);
Here the result of the first one using a Rect:
And here the Second version without a Rect:
Do anybody know what is happening? I need to use the method that uses the rect because I will be creating a bunch of sprites from this image in the future.
Edit1: After debugging both versions of the sprite. I have noticed that the one created without the Rect shows a rect of 0,0,240,240. Instead of 0,0,512,512 as I provided. Why 240?
Thanks in advance.
I managed to figure out what was happening. Cocos2D-x uses director->setContentScaleFactor and glview->setDesignResolutionSize as a way to make things easier for multi resolution/device games. When you build the Rect to get a part (or full) texture you must have into account the CC_CONTENT_SCALE_FACTOR() macro, in order to get correct target coordinates.
This can be checked at this link: http://www.cocos2d-x.org/wiki/Multi_resolution_support
Cheers.
If your vecSize is bigger than the image's size, the image will be out of shape.
So if you don't know the image's real size, don't set it.

Lib Cinder method setup{} in CINDER_APP_BASIC

When my programm start, it must display a circle on a background. Also i must controll all displaying circles. I use class VertexController and class Vertex for that purpose. In Vertex i have constructor:
Vertex::Vertex(const ci::Vec2f & CurrentLoc){
vColor = Color(Rand::randFloat(123.0f),Rand::randFloat(123.0f),Rand::randFloat(123.0f));
vRadius = Rand::randFloat(23.0f);
vLoc = CurrentLoc;
}
and in VertexController i have
VertexController::VertexController()
{
Vertex CenterVertex = Vertex(getWindowCenter());
CenterVertex.draw(); // function-member draw solid circle with random color
}
and in setup{} method i wrote
void TutorialApp::setup(){
gl::clear(Color(255,204,0));
mVertexController=VertexController();
}
Unfrtunatelly, my way didnt work.I see only background.
So the main question - in CINDER_APP_BASIC drawing possible only in draw{},update{},setup{} directly? If yes, advise a solution, else say where is my fail.
this line of code does not make any sense to me:
mVertexController=VertexController();
Anyways, you should use draw() function just for drawing circles to window. This it why by default there is gl::clear(Color(0,0,0)); to clear background and start drawing new frame from scratch (this is the way drawing in OpenGL, used by default in Cinder, works).
I suggest to use Vector container for storing all circles (this way you can add and remove circles on the fly with some effort), add the first one in VertexController constructor, and make separate function VertexController::draw() to draw all circles using for loop.

Changing a texture in real time sdl

Sorry I'm a bit new with SDL and C++ development. Right now I've created a tile mapper that reads from my map.txt file. So far it works, but I want to add editing the map now.
SDL_Texture *texture;
texture= IMG_LoadTexture(G_Renderer,"assets/tile_1.png");
SDL_RenderCopy(G_Renderer, texture, NULL, &destination);
SDL_RenderPresent(G_Renderer);
The above is the basic way I'm showing my tiles, but if I want to go in and change the texture in real time it's kind of buggy and doesn't work well. Is there a method that is best for editing a texture? Thanks for the help I appreciate everything.
The most basic way is to set up a storage container with some textures which you will use repeatedly; for example a vector or dictionary/map. Using the map approach for example you could do something like:
// remember to #include <map>
map<string, SDL_Texture> myTextures;
// assign using array-like notation:
myTextures["texture1"] = IMG_LoadTexture(G_Renderer,"assets/tile_1.png");
myTextures["texture2"] = IMG_LoadTexture(G_Renderer,"assets/tile_2.png");
myTextures["texture3"] = IMG_LoadTexture(G_Renderer,"assets/tile_3.png");
myTextures["texture4"] = IMG_LoadTexture(G_Renderer,"assets/tile_4.png");
then to utilise a different texture, all you have to do is use something along the lines of:
SDL_RenderCopy(G_Renderer, myTextures["texture1"], NULL, &destination);
SDL_RenderPresent(G_Renderer);
which can be further controlled by changing the first line to
SDL_RenderCopy(G_Renderer, myTextures[textureName], NULL, &destination);
where textureName is a string variable which you can alter in code in realtime.
This approach means you can load all the textures you will need before-hand and simply utilise them as needed later, meaning there's no loading from file system whilst rendering:)
There is a nice explanation of map here.
Hopefully this gives you a nudge in the right direction. Let me know if you need more info:)