Welcome, Guest. Please login or register. Did you miss your activation email?

Author Topic: Custom Shape with Texture  (Read 11310 times)

0 Members and 4 Guests are viewing this topic.

Recoil

  • Jr. Member
  • **
  • Posts: 76
    • View Profile
Custom Shape with Texture
« on: June 26, 2019, 05:41:13 pm »
I'm trying to create the graphics for custom shaped buttons.

Currently I can draw a vertex array with 4 points to the screen and set the color of those points to get a solid color shape or gradient shape for a simple rectangular button.

I can even set a sprite from .png image to draw for the button as well.

Instead of drawing a vertex array, or a simple RectangleShape, I would like to draw any shape, and use a rectangle RenderTexture (or other texture), for that shapes texture.

For instance, if I draw a rounded rectangle, I have to draw 5 attached rectangles (center, top, bottom, left, right), then draw a triangle fan at each corner.  I can set all the points to the same color for a solid color.  I can also set the center rectangle points and the triangle fan corner points to one color, and all the outside points to another color for a radial gradient.  However, I cannot apply a vertical or horizontal gradient effect from a rectangle texture over that set of vertices.


I'm not sure if what I am trying to achieve is clear, so I have attached a mock-up image showing what I want to do.  I'm merely looking for the logic of the best way to go about doing this.

Hapax

  • Hero Member
  • *****
  • Posts: 3379
  • My number of posts is shown in hexadecimal.
    • View Profile
    • Links
Re: Custom Shape with Texture
« Reply #1 on: June 26, 2019, 06:23:41 pm »
The texture co-ordinates for each vertex should match which part of the rectangular (as all are 2D) texture should be assigned to that position.
So, for a circle, for example, the points around the circle should have texture co-ordinates that also go around in a circle, around the texture.

An example:

#include <SFML/Graphics.hpp>

int main()
{
    // Load texture
    sf::Texture texture;
    if (!texture.loadFromFile("uv map 1.jpg"))
        return EXIT_FAILURE;

    // Prepare shape
    const sf::Vector2f shapeSize{ 256.f, 256.f };
    constexpr std::size_t numberOfSides{ 12u };
    sf::VertexArray shape;
    shape.resize(numberOfSides + 2u);
    shape.setPrimitiveType(sf::TrianglesFan);

    // Prepare vertices
    for (std::size_t i{ 0u }; i < shape.getVertexCount(); ++i)
    {
        sf::Vector2f position; // normalised circular vertices ranging from 0 - 1 with centre at (0.5, 0.5)
        sf::Vector2f vertexPosition; // shape vertex positions ranging from 0 - shape size (position scaled to shape size)
        sf::Vector2f texturePosition; // shape texture positions ranging from 0 - texture size (texture scaled to texture size)

        if (i == 0)
            position = { 0.5f, 0.5f };
        else
        {
            const float angle{ static_cast<float>(i - 1u) / numberOfSides * 2.f * 3.14159265358979f };
            position = { (1.f + std::cos(angle)) / 2.f, (1.f + std::sin(angle)) / 2.f };
        }
        vertexPosition = { position.x * shapeSize.x, position.y * shapeSize.y };
        texturePosition = { position.x * texture.getSize().x, position.y * texture.getSize().y };

        shape[i].position = vertexPosition;
        shape[i].texCoords = texturePosition;
    }



    // Create window and display shape
    sf::RenderWindow window(sf::VideoMode(800, 600), "Tex Coords", sf::Style::Default);
    while (window.isOpen())
    {
        sf::Event event;
        while (window.pollEvent(event))
        {
            if (event.type == sf::Event::Closed)
                window.close();
        }

        window.clear(sf::Color(128, 128, 128));
        window.draw(shape, &texture); // draw the vertex array using our texture
        window.display();
    }
    return EXIT_SUCCESS;
}



Using render textures is no different since it returns a standard texture to use anyway.
Selba Ward -SFML drawables
Cheese Map -Drawable Layered Tile Map
Kairos -Timing Library
Grambol
 *Hapaxia Links*

Recoil

  • Jr. Member
  • **
  • Posts: 76
    • View Profile
Re: Custom Shape with Texture
« Reply #2 on: June 26, 2019, 09:18:51 pm »
Thanks Hapax for the example, but I think it is above my head in reference to what you are setting the vertex TexCoords to for the new shape.

I have simplified an example of what I am currently doing.  The set of vertices for the top image are at coordinates (20, 20) and a size of (100, 100), and I draw that to a render texture.  I'm not able to draw the render texture to the render window, so I draw a sprite for the RenderTexture.Texture, then draw that sprite to the screen.

Private Sub DrawControlShape()

        Dim posX As Integer = 20
        Dim posY As Integer = 20

        Dim v0 As New Vertex
        Dim v1 As New Vertex
        Dim v2 As New Vertex
        Dim v3 As New Vertex

        ' Set positions
        v0.Position = New Vector2f(posX, posY)
        v1.Position = New Vector2f(posX + 100, posY)
        v2.Position = New Vector2f(posX + 100, posY + 100)
        v3.Position = New Vector2f(posX, posY + 100)

        ' Gradient colors
        v0.Color = Color.Red
        v1.Color = Color.Blue
        v2.Color = Color.Yellow
        v3.Color = Color.Green

        ' Draw to show working
        m_engineWindow.Draw({v0, v1, v2, v3}, PrimitiveType.Quads)


        ' Create render texture
        m_renderTexture = New RenderTexture(100, 100)
        m_renderTexture.Clear()
        m_renderTexture.Draw({v0, v1, v2, v3}, PrimitiveType.Quads)
        m_renderTexture.Display()

        ' Create sprite
        m_sprite = New Sprite(m_renderTexture.Texture)
        m_sprite.Position = New Vector2f(posX, posY + 100)
        m_sprite.TextureRect = New IntRect(0, 0, 100, 100)

        ' Draw to show working
        m_engineWindow.Draw(m_sprite)

    End Sub
 
While this may be a separate issue, I do not understand why I have an offset when drawing the sprite from the render texture:


At any rate, when I create a rounded rectangle shape with vectors and triangle fans, I am not sure what to set each vertices to:

v0.TexCoords = ?
 

Edit:

Okay, so I don't need the sprite.  Once I draw the vertices to the render texture I have to set the texture and textureRect of Shapes (rectangle/circle/convex/etc).  I was thinking this had to be done another way.  I still don't fully understand the offsets for the positions and textureRects, but I'll work it out.



Edit2:

It doesn't seem that I am able to apply the same vertical/horizontal gradient effect over the rounded rectangles.  I can draw all the points with a circle gradient like normal to a render texture, then draw a new rectangle shape to the screen with that same render texture, but unable to apply another texture on it that keeps the fan edges and draws just a gradient rectangle instead of a rounded one.
« Last Edit: June 27, 2019, 02:01:47 am by Recoil »

Recoil

  • Jr. Member
  • **
  • Posts: 76
    • View Profile
Re: Custom Shape with Texture
« Reply #3 on: June 27, 2019, 02:32:36 pm »
For some reason I can draw a vertical/horizontal render texture to actual SFML shapes, but not drawn points like I am creating for the rounded rectangle with the triangle fans.  So I am approaching this another way different from the previous reply and edits.

I am making an attempt to convert this so I can use it like other shapes:
Source: Draw Rounded Rectangle

Here is the class I have converted from that link:
Imports System.Math
Imports SFML.System
Imports SFML.Graphics

Public Class RoundedRectangleShape
    Inherits Shape

    Dim mySize As Vector2f
    Dim myRadius As Single
    Dim myCornerPointCount As UInteger

    Public Sub SetSize(ByVal size As Vector2f)
        mySize = size
        Update()
    End Sub

    Public Function GetSize()
        Return mySize
    End Function

    Public Sub SetCornerRadius(ByVal radius As Single)
        myRadius = radius
        Update()
    End Sub

    Public Function GetCornerRadius()
        Return myRadius
    End Function

    Public Sub SetCornerPointCount(ByVal count As UInteger)
        myCornerPointCount = count
        Update()
    End Sub

    Public Overrides Function GetPointCount() As UInteger
        Return myCornerPointCount * 4
    End Function

    Public Sub New(ByVal size As Vector2f, ByVal radius As Single, ByVal cornerPointCount As UInteger)

        mySize = size
        myRadius = radius
        myCornerPointCount = cornerPointCount
        Update()

    End Sub

    Public Overrides Function GetPoint(ByVal index As UInteger) As Vector2f

        If index >= myCornerPointCount * 4 Then

            Return New Vector2f(0, 0)

        End If

        Dim deltaAngle As Single = 90.0F / (myCornerPointCount - 1)
        Dim center As Vector2f
        Dim centerIndex As UInteger = index / myCornerPointCount
        Dim pi As Single = 3.14159274F

        Select Case (centerIndex)
            Case 0
                center.X = mySize.X - myRadius
                center.Y = myRadius
            Case 1
                center.X = myRadius
                center.Y = myRadius
            Case 2
                center.X = myRadius
                center.Y = mySize.Y - myRadius
            Case 3
                center.X = mySize.X - myRadius
                center.Y = mySize.Y - myRadius
        End Select

        Return New Vector2f(myRadius * Cos(deltaAngle * (index - centerIndex) * pi / 180) + center.X, -myRadius * Sin(deltaAngle * (index - centerIndex) * pi / 180) + center.Y)

    End Function

End Class
 


Implementation in loop:
Dim roundedRectangle As New GFX_Control_Library.RoundedRectangleShape(New Vector2f(75, 25), 5, 3)
        roundedRectangle.SetSize(New Vector2f(75, 25))
        roundedRectangle.SetCornerRadius(5)
        roundedRectangle.SetCornerPointCount(3)
        roundedRectangle.Position = New Vector2f(140, 20)
        roundedRectangle.OutlineThickness = 1
        roundedRectangle.OutlineColor = Color.Blue
        roundedRectangle.Texture = m_renderTexture.Texture
        roundedRectangle.TextureRect = New IntRect(20, 20, 95, 45)
        m_engineWindow.Draw(roundedRectangle)
 

Here is my result:


I will be honest, I do not fully understand how this is working as the GetPoint function in the class works differently than the way points are being set drawing a rounded rectangle with triangle fans.  However, it looks like the 2 points on the right side are pulled to the left, and I have no idea where to start on correcting that.

Please tell me someone understand what is going on  :-[?

Edit:

Okay, so  looped through the debugger and noticed that it was only hitting [Case 0] 3 times while it hit the others 5, then looping through twice and returning the last 2 set values instead of a Case.  So I added this to the bottom:
Case Else
                center.X = mySize.X - myRadius
                center.Y = myRadius
 

I increased the radius size to 10, and this is what I get now:


So I'm getting closer, but I do not see a way to pull back the starting points.  After messing with a few settings I noticed this is drawing backwards, with position 0 at the top right, position 1 at the top left, and continuing counter clockwise.  It is drawing in the correct position I set it to though.

I believe this issue has something to do with the way the base Shape class draws the custom shapes, but honestly am not certain.  I'm hoping for some ideas on what I might be doing wrong so the starting points of the radii can draw in the correct position.
« Last Edit: June 27, 2019, 06:35:29 pm by Recoil »

Hapax

  • Hero Member
  • *****
  • Posts: 3379
  • My number of posts is shown in hexadecimal.
    • View Profile
    • Links
Re: Custom Shape with Texture
« Reply #4 on: June 27, 2019, 08:26:28 pm »
Firstly, I'd like to apologise as I didn't notice that this was under DotNet so my C++ example may not have been as useful.

Secondly, it looks like your extra offset with the render texture is because you're offsetting when drawing to the render texture and then offsetting the actual drawing of the render texture. You should draw at 0, 0 and fill the render texture (or whatever size you need) and make sure that your texture rectangle (or texCoords with a vertex array) start from (0, 0). Then, offset the shape/vertices as normal.

The thing is that the texture coordinate is specifying which part of the texture should be at that vertex. If you draw the same shape on the render texture with your texture coordinates, it should start to be okay. It looks like you got a circle with a texture fine, to be fair.

Just to try to explain my example code a little:
For each vertex, I calculated its position in the circle as if the circle was within the rectangle (0, 0) to (1, 1) with the circle's centre at (0.5, 0.5). I then scaled that by the required shape's size and assigned that to its position. Then, I scaled it by, instead, the size of the texture and assigned it to its texCoords. This means that it 'draws a circle' (or ellipse/oval if texture is not square) around the texture; it sort of cuts it out.

Probably the simplest way to start would be to assign the same co-ordinate to texture coordinates as its position. Just remember that they should probably be offset by the negative amount that the whole shape has been offset (so that the texture starts at (0, 0) - the top left corner of the texture. This applies to render textures too.


One thing to note, though, is that if your texture coordinates don't match the same shape as the positions, the texture will 'twist' and the individual triangles will probably be visible.
Selba Ward -SFML drawables
Cheese Map -Drawable Layered Tile Map
Kairos -Timing Library
Grambol
 *Hapaxia Links*

Recoil

  • Jr. Member
  • **
  • Posts: 76
    • View Profile
Re: Custom Shape with Texture
« Reply #5 on: June 27, 2019, 10:11:23 pm »
The bulk majority of people here don't program in VB.NET or C#, so it's understandable  :).  I appreciate all the advice I can get.

As far as this example goes, I was using a RectangleShape, CircleShape, and ConvexShape, with the texture for them coming from the RenderTexture.  The top left square is drawing the vertices straight to the screen jut to show what and where the RenderTexture is.  The offset issue makes complete sense now.


However, I didn't know I was still having issues drawing a render texture over a set of vertices.  I wanted to be able to draw any shape with vertices and texture over them with any texture (vertical/horizontal/radial gradients).  While this process works for existing Shapes, it will not work for something like the rounded rectangle where I have to set the individual points with colors and draw to the screen.

This example I am drawing all the vertices of a rounded rectangle directly to the screen (since you helped me previously with that and I had that shape).  It is drawing at position (0, 0) for clarity with the cyan/magenta gradient.  For the same points I am drawing to a RenderTexture as well at the same location.  To the right is a Sprite with the texture from the first RenderTexture, and under that is a Sprite with the second RenderTexture.  The problem I am having is being able to keep the shape, but overlay another texture onto it.  For example, take the texture from the top right sprite, and overlay it onto the bottom right sprite white keeping the same shape that I drew all the vertices for.


So in the next post I decided to try and convert the C++ RoundedRectangle class and use it.  Because it is a shape I can texture it just like I do the ones in the first image, and it looks like that part works.  However, the problem I am running into with using that shape class is a bit over my head as I do not know how to correct the points.  I'm not sure if this has something to do with the base Shape class, or how I have converted to GetPoint function, but my lack of C++fu probably doesn't help.


All this is for my graphics control library I have been working on/off with for a while now.  It took forever but I finally nailed down passing click events for drawn objects in order to make controls, since I could never get any of the preexisting control libraries to work in VB.NET.  The base class handles drawing the shapes of each control, so the appearance effects is applicable to a panel like it is a button.  Having customizable shaped controls would be great, but not necessary.  I feel like I am close to resolving this one way or another though, and there might be another way I have not even thought of yet to make this work.

Hapax

  • Hero Member
  • *****
  • Posts: 3379
  • My number of posts is shown in hexadecimal.
    • View Profile
    • Links
Re: Custom Shape with Texture
« Reply #6 on: June 27, 2019, 10:33:28 pm »
Not 100% sure but I think if you're using something that inherits from sf::Shape then you only need to set the texture rectangle.

If you're creating textured buttons, it would be probably be advantageous to look into scalable textured buttons using something called Nine Patch (or nine slice). Selba Ward's Nine Patch implements them to be used with SFML. For more information on what a nine patch is, have a look at this. For more information on Selba Ward and its drawables, see its wiki and its SFML forum thread (or just ask me!).

Anyway, have you tried creating a vertex array with the shape you want, at position (0, 0), and with the same texture coordinates. Did this work?
Selba Ward -SFML drawables
Cheese Map -Drawable Layered Tile Map
Kairos -Timing Library
Grambol
 *Hapaxia Links*

Recoil

  • Jr. Member
  • **
  • Posts: 76
    • View Profile
Re: Custom Shape with Texture
« Reply #7 on: June 28, 2019, 12:17:31 am »
I already have it set where I can use .png images for controls, but I was going to try and convert some of what you have on Selba Ward eventually for this thing because I would like to use the Bitmap Text.  Converting from C++ takes some time though  ;D

However, yes I have tried plotting the TexCoords when I set the positions, but it isn't plotting them from anything if that makes sense.  I have the original rainbow gradient RenderTexture1 drawing at the top.  I draw the vertices of a n-sided shape on RenderTexture2, along with the TexCoords set to RenderTexture2's position.  Then I can draw a Sprite onto the RenderWindow using 1 RT or the other.  But I don't know how to draw the vertices and apply a texture that display over them and not have to use colors.

I don't get the option to set the TexCoords along with what RT they are using:
        Dim position As New Vector2f(0, 0)
        Dim size As New Vector2f(150, 50)

        m_renderTexture2 = New RenderTexture(150, 50)
        m_renderTexture2.Clear()

        Dim v0 As New Vertex
        v0.Position = New Vector2f(position.X + 5, position.Y)
        v0.TexCoords = New Vector2f(position.X, position.Y)

        Dim v1 As New Vertex
        v1.Position = New Vector2f(position.X + size.X - 5, position.Y)
        v1.TexCoords = New Vector2f(position.X + size.X, position.Y)

        Dim v2 As New Vertex
        v2.Position = New Vector2f(position.X + size.X, position.Y + size.Y)
        v2.TexCoords = New Vector2f(position.X + size.X, position.Y + size.Y)

        Dim v3 As New Vertex
        v3.Position = New Vector2f(position.X, position.Y + size.Y)
        v3.TexCoords = New Vector2f(position.X, position.Y + size.Y)

        m_renderTexture2.Draw({v0, v1, v2, v3}, PrimitiveType.Quads)
        m_renderTexture2.Display()

        Dim sprt As New Sprite(m_renderTexture2.Texture, New IntRect(0, 0, 150, 50))
        sprt.Position = New Vector2f(20, 100)
        m_engineWindow.Draw(sprt)
        sprt.Dispose()

        m_renderTexture2.Dispose()
 

I can still draw a radial gradient shape though, but I cannot apply a separate RT onto it, like in this image:


Right now I am considering just doing a ConvexShape for a rounded rectangle so I can apply a RT over that, but it is going to take some work to get running.  It is probably my best option.

Edit:

And that is exactly what I did - used a ConvexShape, along with all the code you helped me out with for drawing the radial gradient a while back, and applied the RenderTexture over it.  I may create a new thread with a class file for a textured rounded rectangle and update this thread with a link for people searching.


« Last Edit: June 28, 2019, 04:13:00 am by Recoil »

Hapax

  • Hero Member
  • *****
  • Posts: 3379
  • My number of posts is shown in hexadecimal.
    • View Profile
    • Links
Re: Custom Shape with Texture
« Reply #8 on: June 28, 2019, 10:05:26 pm »
I'm not sure I understand which part you have working and which you don't.

Did you say that you're drawing the shape on the render texture?
The render texture should be filled with the texture; it can be a rectangle. The shape/vertex array is drawn to the window using the render texture as its texture. This is the vertex array that should use texture co-ordinates similar to positions.
This way, it's like the shape you draw become a "cookie-cutter" for the texture passed to it (your render texture's texture).
I'm not sure why you're using a sprite...



I've written a more thorough example that shows a render texture getting used as a texture for slightly more complicated shapes.
Similarly to the previous example, it creates the circle points but this time it randomly scales their radii, creating a 'random spikey' object.
I've also added comments to explain a little better what is going on.

I hope it's easy enough for you to follow as it's still C++.

Here are 3 screenshots from this program:




Here's the code with comments:
// this generates a randomised triangle fan using a render texture as its texture base
// it shows that the (render) texture need not know the final shape on which it is used

// the shape can be re-generated by pressing SPACE

#include <SFML/Graphics.hpp>
#include <random>
#include <functional>
#include <iostream>

bool generateRenderTexture(sf::RenderTexture& renderTexture)
{
    // Load texture
    sf::Texture texture;
    if (!texture.loadFromFile("uv map 1.jpg")) // the image I used here is sized 256x256
        return false;

    renderTexture.create(texture.getSize().x, texture.getSize().y);
    renderTexture.clear();
    renderTexture.draw(sf::Sprite(texture)); // draw the full texture onto the render texture
    renderTexture.display();

    // at this point, we have a render texture that is exactly the same size as the texture and is visually indentical to the texture; we can now use it as a normal texture
    // if you want to use a gradient, say, instead of an image then create a square that fills the render texture with the gradient and draw it to the render texture instead

    return true;
}

void prepareVertices(sf::VertexArray& shape, const sf::Vector2u size)
{
    // prepare random
    std::default_random_engine randomGenerator;
    randomGenerator.seed(std::random_device()());
    std::uniform_real_distribution<float> randomAlphaDistribution{ 0.f, 1.f }; // "alpha" distribution (from 0 to 1)

    // properties
    const sf::Vector2f shapeOffset{ 128.f, 64.f };
    const std::size_t numberOfSides{ shape.getVertexCount() - 2u };

    // this calculates the points of a circle from vertex 1 onwards; vertex 0 is the centre of the circle (the start of the triangle fan)
    // each of those points have their radii scaled randomly to create a random 'pointy' shape
    // these points are convertex from their original range (-1 to 1) to a normalised range (0 to 1)
    // this means that the origin (0, 0) is a the top-left of the circle's bounding box
    // it is then scaled to match the size of the render texture
    // the vertex positions are then offset by "shapeOffset" to allow the shape to move away from the origin without moving which part of the texture is used
    for (std::size_t i{ 0u }; i < shape.getVertexCount(); ++i)
    {
        sf::Vector2f position; // normalised circular vertices ranging from 0 - 1 with centre at (0.5, 0.5)
        sf::Vector2f texturePosition; // (position scaled to size)

        if (i == 0)
            position = { 0.5f, 0.5f }; // first vertex is in the centre to begin the triangle fan
        else
        {
            // calculate circle point's position using sine and cosine. the radius of this point is scaled by a random value
            const float angle{ static_cast<float>(i - 1u) / numberOfSides * 2.f * 3.14159265358979f };
            const sf::Vector2f circlePoint{ std::cos(angle), std::sin(angle) }; // ranging from -1 to 1 on each axis
            const float radiusScale{ randomAlphaDistribution(randomGenerator) }; // scale the radius of each point separately by a random amount
            position = { (1.f + std::cos(angle) * radiusScale) / 2.f, (1.f + std::sin(angle) * radiusScale) / 2.f }; // ranging from 0 to 1 on each axis
        }
        texturePosition = { position.x * size.x, position.y * size.y };

        shape[i].position = texturePosition + shapeOffset;
        shape[i].texCoords = texturePosition;
    }
}

int main()
{
    // prepare random
    std::default_random_engine randomGenerator;
    randomGenerator.seed(std::random_device()());
    std::uniform_real_distribution<float> randomAlphaDistribution{ 0.f, 1.f }; // "alpha" distribution (from 0 to 1)

    // Prepare render texture
    sf::RenderTexture renderTexture;
    if (!generateRenderTexture(renderTexture))
        return EXIT_FAILURE;

    // Prepare shape
    constexpr std::size_t numberOfSides{ 36u };
    sf::VertexArray shape;
    shape.resize(numberOfSides + 2u);
    shape.setPrimitiveType(sf::TrianglesFan);

    // Generate vertices for shape (circle but with each point having a random radius)
    prepareVertices(shape, renderTexture.getSize());



    // Create window and display shape
    sf::RenderWindow window(sf::VideoMode(512, 384), "Tex Coords", sf::Style::Default);
    while (window.isOpen())
    {
        sf::Event event;
        while (window.pollEvent(event))
        {
            switch (event.type)
            {
            case sf::Event::Closed:
                window.close();
                break;
            case sf::Event::KeyPressed:
                switch (event.key.code)
                {
                case sf::Keyboard::Escape:
                    window.close();
                    break;
                case sf::Keyboard::Space:
                    prepareVertices(shape, renderTexture.getSize()); // re-generate vertices (randomised)
                    break;
                }
                break;
            }
        }

        window.clear(sf::Color(128, 128, 128));
        window.draw(shape, &renderTexture.getTexture()); // draw the vertex array using our render texture
        window.display();
    }
    return EXIT_SUCCESS;
}



EDIT: added new example
« Last Edit: June 29, 2019, 01:55:04 am by Hapax »
Selba Ward -SFML drawables
Cheese Map -Drawable Layered Tile Map
Kairos -Timing Library
Grambol
 *Hapaxia Links*

Recoil

  • Jr. Member
  • **
  • Posts: 76
    • View Profile
Re: Custom Shape with Texture
« Reply #9 on: June 29, 2019, 05:03:02 am »
The Sprite was used to draw the RenderTexture exactly the size, shape, and location to demonstrate what I was pulling the texture from, and what it looked like.

And that was what I was trying to do - draw the shape with vertex points, then set a RenderTexture over that.  However, the only method I knew to try is drawing the vertices with a color, then drawing that to the screen.  I was not able to use a RenderTexture over that even when removing the colors.  The only way I could get this to work correctly was with actual shapes from the SFML Shape class.

I fixed the class file so it works, but it is completely different from the C++ example of a rounded rectangle, because I had issues moving the starting points where the radii are, which gave me a rectangle with blobbed corners.  When I converted this to VB code there was no way I could figure out to correct those points, without overriding the whole base Shape class to accept a vertex array on GetPoint function...which is a bit too much work to take on.

Here is an example that I am doing now.  All 4 RenderTextures are drawn at point (0, 0) and a size of (100, 100).  I am not using a sprite to show where they are.  This is using my new class, with a different RenderTexture for each one used:


The rounded gradient could use some work, but I know how to fix that by drawing a larger rounded rectangle with gradient colors for the points.

Thank you for the example.  Since I have been working on converting C++ examples it is easier to understand what is going on under the hood, and how to make things work for me, and what wont.  I am going to give that a shot when I have some free time after the weekend.
« Last Edit: June 29, 2019, 05:07:45 am by Recoil »

Hapax

  • Hero Member
  • *****
  • Posts: 3379
  • My number of posts is shown in hexadecimal.
    • View Profile
    • Links
Re: Custom Shape with Texture
« Reply #10 on: June 30, 2019, 01:18:53 am »
Looks like you got it sorted now. Nice one!

If you want a radial gradient, you could consider using this Radial Gradient shader when you draw the quad to the render texture. ;)
Selba Ward -SFML drawables
Cheese Map -Drawable Layered Tile Map
Kairos -Timing Library
Grambol
 *Hapaxia Links*

Recoil

  • Jr. Member
  • **
  • Posts: 76
    • View Profile
Re: Custom Shape with Texture
« Reply #11 on: June 30, 2019, 02:17:16 pm »
I have tried implementing shaders in vb.net previously, and come across the example you linked for something that "looked" simple enough to get converted into the language.  There are a few things I could never get translated over because I do not believe there is a way to do it in vb.

Anything with the "Uniform" keyword:
"uniform vec4 color;"
 

And this, it is assigning variables from other variables, but those variables aren't defined anywhere in the code:
const char VertexShader[] =
"void main()"
"{"
        "gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;"
        "gl_TexCoord[0] = gl_TextureMatrix[0] * gl_MultiTexCoord0;"
        "gl_FrontColor = gl_Color;"
"}";
 

Sometimes I think I am the only hobby programmer here using vb.net for their choice of language to use, which means anything I want to do I am kinda breaking new ground with.  But it looks like in order to use shaders at all I would have to switch to a language with brackets...I'm just not that smart  :D