I have a texture drawn in a GLcontrol and I want to draw points on top of it. Instead, I get the full texture set to the colour of the point I want to draw. I guess that I have to disable the texture format and enable the points drawings, but cant reach the solution...
Here is the draw function:
Basically the point to draw is ROI[0], but instead drawing just the point I got the image shown below (the image is grayscale before drawing "the point").
private: void drawImg(int img){
int w=this->glControl_create_grid->Width;
int h=this->glControl_create_grid->Height;
GL::MatrixMode(MatrixMode::Projection);
GL::LoadIdentity();
GL::Ortho(0, w, 0, h, -1, 1); // Bottom-left corner pixel has coordinate (0, 0)
GL::Viewport(0, 0, w, h); // Use all of the glControl painting area
GL::Clear(ClearBufferMask::ColorBufferBit | ClearBufferMask::DepthBufferBit);
GL::ClearColor(Color::LightGray);
GL::MatrixMode(MatrixMode::Modelview);
GL::LoadIdentity();
GL::Enable(EnableCap::Texture2D);
GL::BindTexture(TextureTarget::Texture2D, img);
OpenTK::Graphics::OpenGL::ErrorCode error=GL::GetError();
GL::Begin(BeginMode::Quads);
GL::TexCoord2(0, 0);
GL::Vertex2(0 ,h);
GL::TexCoord2(1, 0);
GL::Vertex2(w, h);
GL::TexCoord2(1, 1);
GL::Vertex2(w, 0);
GL::TexCoord2(0, 1);
GL::Vertex2(0, 0);
GL::End();
GL::Disable(EnableCap::Texture2D);
if (ROI[0].x!=0||ROI[0].y!=0){
GL::Color3(Color::Red);
GL::Begin(BeginMode::Points);
GL::Vertex2(ROI[0].x,ROI[0].y);
GL::End();
}
}
What should I change in my code? I can't seem to achieve it....
I found the answer. It seems that the color also applies to textures when binding them so I just needed to add GL::Color3(Color::White) before drawing the texture.
Related
So, I'm making a 2D game and I have some textures. I will like some of them to drop a shadow, there is something like drop-shadow in css for SDL2?
Render the texture first, then render a slightly larger semi-transparent gray square slightly behind it. If you want rounded corners, use a shader that increases alpha as you get further from the corners.
Since noone mentionned it yet, here it is:
int SDL_SetTextureColorMod(SDL_Texture* texture,
Uint8 r,
Uint8 g,
Uint8 b)
https://wiki.libsdl.org/SDL_SetTextureColorMod
This function multiplies a texture color channels when copying it to the SDL_Renderer*. Using it with 0 as r, g and b arguments would make your texture pitch black but not affect the alpha, so the texture would keep its shape (like in the case of a transparent PNG). You just have to copy that shadow before (= behind) your texture, with a slight offset. You can also change the overall transparency of the shadow, with SDL_SetTextureAlphaMod(SDL_Texture* texture, Uint8 a)
Just don't forget to set the values back to 255 when you're done.
Code example:
SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
SDL_RenderClear(renderer);
// [...] draw background, etc... here
SDL_Rect characterRect;
// [...] fill the rect however you want
SDL_Rect shadowRect(characterRect);
shadowRect.x += 30; // offsets the shadow
shadowRect.y += 30;
SDL_SetTextureColorMod(characterTexture, 0, 0, 0); // makes the texture black
SDL_SetTextureAlphaMod(characterTexture, 191); // makes the texture 3/4 of it's original opacity
SDL_RenderCopy(renderer, characterTexture, NULL, &shadowRect); // draws the shadow
SDL_SetTextureColorMod(characterTexture, 255, 255, 255); // sets the values back to normal
SDL_SetTextureAlphaMod(characterTexture, 255);
SDL_RenderCopy(renderer, characterTexture, NULL, &characterRect); // draws the character
// [...] draw UI, additionnal elements, etc... here
SDL_RenderPresent(renderer);
I have finally started getting used to SDL 2's basic functions for rendering and I have stumbled across a problem that I believe the public might be able to answer. In my code I generate some text and using some code from a tutorial, am able to load the text as a texture (namely Lazy foo's tutorial). This texture now has a width and a height based on font size and how much text was entered. Another function I use loads in a square made of fancy boardering that I wish to use as a menu. This square is 200x200. As an example, if the text texture is 100x160, I want the square to now render as perhaps a 120x180 image (essentially compressing it to be a similar size as the text texture.
tl;dr:
I have 200x200 square.
I have 100x160 text texture
I want to render 200x200 square as a 120x160 square and render 100x160 text inside square.
***loadFromRenderedText takes a ttf font, a string, and a color (RGBA) to create an image texture based on the string -> generates own width/height
menuTextTexture.loadFromRenderedText(menuFont, "Info Item Skill Back",menuTextColor);
menuSize.x = 0;
menuSize.y = 0;
menuSize.w = menuTextTexture.getWidth() + boarderW;
menuSize.h = menuTextTexture.getHeight() + boarderW;
***menuSize is an SDL_Rect
menuBoxTexture.TextRender(XmenuRenderLocX, XmenuRenderLocY, &menuSize, 0, NULL, SDL_FLIP_NONE);
menuTextTexture.render(XmenuRenderLocX+boarderW, XmenuRenderLocY+boarderW);
TextRender and render do the same thing except render uses a scaling factor to multiply the clip size to be bigger (which I leave blank -> clip is then NULL and the basic height/width are used). For TextRender, I specify the render dimensions by passing the menuSize SDL rect. this takes the 200x200 square and renders only the 120x160 of the square at the (XmenuRenderLocX, XmenuRenderLocY)... thus essentially cropping the square, which is not what I want... I want to resize the square.
Any help will be greatly appreciated
Originally, I was using the provided LTexture::render function that was created for Lazy Foo's tutorial. See below code
void LTexture::render( int x, int y, SDL_Rect* clip, double angle, SDL_Point* center, SDL_RendererFlip flip )
{
//Set rendering space and render to screen
SDL_Rect renderQuad = { x, y, mWidth, mHeight };
//Set clip rendering dimensions
if( clip != NULL )
{
renderQuad.w = SCALE_SIZE*(clip->w);
renderQuad.h = SCALE_SIZE*(clip->h);
}
else if(mTexture ==NULL)
{
printf("Warning: Texture to Render is NULL!\n");
}
//Render to screen
SDL_RenderCopyEx( gRenderer, mTexture, clip, &renderQuad, angle, center, flip );
}
But because I didn't fully understand until now how exactly the function renders, I wasn't actually telling it to render at a new dimension (except in the case where I magnify everything with a SCALE_SIZE)
I made a new function for more control
void LTexture::DefinedRender(SDL_Rect* Textureclip, SDL_Rect* renderLocSize, double angle, SDL_Point* center, SDL_RendererFlip flip)
{
//Set clip rendering dimensions
if(mTexture ==NULL)
{
printf("Warning: Texture to Render is NULL!\n");
}
//Render to screen
SDL_RenderCopyEx( gRenderer, mTexture, Textureclip, renderLocSize, angle, center, flip );
}
And now everything works like I want it to.
I am using a FrameBuffer to rasterize several TextureRegions in a single TextureRegion, to be drawn on an Image/Actor afterwards.
The constructor of a FrameBuffer is the following:
FrameBuffer(Pixmap.Format format, int width, int height, boolean hasDepth)
I found that if I put Gdx.graphics.getWidth()/getHeight() as the width and height parameters in the constructor the image is drawn correctly, but if I put something else (like the rasterized texture size) the texture is way smaller and is pixelated if I increase the size. Have I missed something ?
TextureRegion initialTexture = getTexture();
// And other textures, which are not shown here for better readability
FrameBuffer frameBuffer = new FrameBuffer(Pixmap.Format.RGBA8888, (int)initialTexture.getRegionWidth(), (int)initialTexture.getRegionHeight(), false);
Batch batch = new SpriteBatch();
// Adding these lines did the trick
Camera camera = new OrthographicCamera(frameBuffer.getWidth(), frameBuffer.getHeight());
camera.position.set(frameBuffer.getWidth() / 2, frameBuffer.getHeight() / 2, 0);
camera.update();
batch.setProjectionMatrix(camera.combined);
frameBuffer.begin();
batch.enableBlending();
Gdx.gl.glBlendFuncSeparate(GL20.GL_SRC_ALPHA, GL20.GL_ONE_MINUS_SRC_ALPHA, GL20.GL_ONE, GL20.GL_ONE_MINUS_SRC_ALPHA);
Gdx.gl.glClearColor(1, 1, 1, 0);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
batch.begin();
batch.setColor(TAPColor.TAP_WHITE);
batch.draw(initialTexture, 0, 0);
// Also draw other textures
batch.end();
frameBuffer.end();
TextureRegion finalTexture = new TextureRegion(frameBuffer.getColorBufferTexture());
Image image = new Image(finalTexture);
image.setSize(finalTexture.getRegionWidth(), finalTexture.getRegionHeight());
image.setPosition(0, 0);
addActor(image);
I had some problems too, one thing that made it simple was:
Matrix4 projection = new Matrix4();
projection.setToOrtho2D(0, 0, 32, 48);
batch.setProjectionMatrix(projection);
Usually with Processing, you fill a rectangle with a given color like so:
fill(255, 0, 0); // Make it red
rect(0,0, 100, 100); // Make it square
However, this does not work. Instead, the rectangle displays this shader. Somewhere earlier in the execution I call this:
PShader shader = loadShader(filePath); // A shader is loaded once upon startup
// In a draw() method
shader(shader);
rect(0, 0, screenWidth, screenHeight);
This draws a rectangle which covers the whole screen, and a nice dynamic background is displayed.
Why does the fill() call have no effect and why is the shader drawn in the rectangle instead? How can I keep the background shader and also display a red rectangle in Processing?
I am trying to create a god's ray effect from scratch using libgdx and opengl shader langage. To do this I use a background image as light source, then I apply another texture as a mask setting the spriteBatch color to full black.
background texture
mask texture
the mask is then rendered in full black over the background
Color batchColor = batch.getColor();
fbo1.begin();
batch.begin();
batch.draw(textureBackground, 0, 0, w, h);
batch.setColor(Color.BLACK);
batch.draw(textureBar, 0, 0, w, h);
batch.setColor(batchColor);
batch.end();
fbo1.end();
then the god's ray shader is applied
Sprite rayEffect = new Sprite(fbo1.getColorBufferTexture());
rayEffect.flip(false, true);
fbo2.begin();
batch.setShader(shaderGodRay);
batch.begin();
rayEffect.draw(batch);
batch.end();
batch.setShader(null);
fbo2.end();
The rays are ok at this stage. Know I would like to blend the original mask color with the rendered rays in order to obtain the final image. Only rendering the mask again on top of the rays are totally overlapped by the colored mask
rayEffect = new Sprite(fbo2.getColorBufferTexture());
rayEffect.flip(false, true);
batch.begin();
rayEffect.draw(batch);
batch.draw(textureBar, 0, 0, w, h);
batch.end();
I think alpha blending should do the trick, but on my ray rendered image, the opacity is full.
Does someone know how I may blend the two texture together in order to obtain the desired final result?