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

Show Posts

This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.


Topics - Bogdan

Pages: [1] 2
1
General / SFML Opengl Shader [solved]
« on: February 27, 2024, 04:54:27 pm »
I'm learning Opengl with SFML right now...but there seems to be an unknown problem with the code, because the shader doesn't work (no color; mesh is just white). Maybe someone can help out, please?

#include <GL/glew.h>
#include <SFML/Window.hpp>
#include <SFML/OpenGL.hpp>
#include <iostream>
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <string>
#include <glm/gtc/type_ptr.hpp>
#include <GL/gl.h>
#include <vector>


class Shader
{
public:
        Shader(const std::string& vertexCode, const std::string& fragmentCode);
        void Use();
private:
        uint32_t programID{};

};


Shader::Shader(const std::string& vertexCode, const std::string& fragmentCode)
{
        const char* vertexShaderCode = vertexCode.c_str();
        const char* fragmentShaderCode = fragmentCode.c_str();


        // vertexshader
        size_t vertexShader = glCreateShader(GL_VERTEX_SHADER);
        glShaderSource(vertexShader, 1, &vertexShaderCode, nullptr);
        glCompileShader(vertexShader);

        int success{};
        char infoLog[1024]{};
        glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &success);
        if (!success)
        {
                glGetShaderInfoLog(vertexShader, 1024, nullptr, infoLog);
                std::cerr << "Failed to compile shader!\nInfoLog:\n" << infoLog;
        }

        //fragmentshader
        size_t fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
        glShaderSource(fragmentShader, 1, &fragmentShaderCode, nullptr);
        glCompileShader(fragmentShader);

        glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &success);
        if (!success)
        {
                glGetShaderInfoLog(fragmentShader, 1024, nullptr, infoLog);
                std::cerr << "Failed to compile shader!\nInfoLog:\n" << infoLog;
        }
        //

        size_t programID = glCreateProgram();
        glAttachShader(programID, vertexShader);
        glAttachShader(programID, fragmentShader);
        glLinkProgram(programID);

        glGetProgramiv(programID, GL_LINK_STATUS, &success);
        if (!success)
        {
                glGetProgramInfoLog(programID, 1024, nullptr, infoLog);
                std::cerr << "Failed to link shader!\nInfoLog:\n" << infoLog;
        }
        glDeleteShader(vertexShader);
        glDeleteShader(fragmentShader);
}

void Shader::Use()
{
        glUseProgram(programID);

}




class Mesh
{
public:
        Mesh(std::vector<glm::vec3> vertices, std::vector<uint32_t> indices);
        void Draw() const;
private:
        std::vector<glm::vec3> vertices;
        std::vector<uint32_t> indices;

        uint32_t vao, vbo, ebo;
};

Mesh::Mesh(std::vector<glm::vec3> vertices, std::vector<uint32_t> indices)
        : vertices(vertices), indices(indices), vao(), vbo(), ebo()
{
        glGenBuffers(1, &vbo);
        glGenBuffers(1, &ebo);
        glGenVertexArrays(1, &vao);

        glBindVertexArray(vao);

        glBindBuffer(GL_ARRAY_BUFFER, vbo);
        glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(glm::vec3), vertices.data(), GL_STATIC_DRAW);

        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo);
        glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.size() * sizeof(glm::uint32_t), indices.data(), GL_STATIC_DRAW);

        glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), nullptr);
        glEnableVertexAttribArray(0);

        glBindBuffer(GL_ARRAY_BUFFER, 0);
        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
        glBindVertexArray(0);

}

void Mesh::Draw() const
{
        glBindVertexArray(vao);
        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo);
        glDrawElements(GL_TRIANGLES, indices.size(), GL_UNSIGNED_INT, nullptr);
}

int main()
{
        const char* vertexShaderCode = "#version 330 core\n"
                "layout (location = 0) in vec3 pos;\n"
                "void main() { gl_Position = vec4(pos, 1.0); }\n";

        const char* fragmentShaderCode = "#version 330 core\n"
                "out vec4 FragColor;\n"
                "void main() { FragColor = vec4(0.0, 0.0, 1.0, 1.0); }\n";

        sf::Window window(sf::VideoMode(800, 800), "3D OpenGL");

        if (glewInit() != GLEW_OK)
        {
                std::cerr << "Failed to initialize GLEW\n";
                return -1;
        }

        Shader shader(vertexShaderCode, fragmentShaderCode);

        Mesh mesh({
                glm::vec3(0.8f,  0.8f, 0.0f), // top right
                glm::vec3(0.8f, -0.8f, 0.0f), // bottom right
                glm::vec3(-0.8f,-0.8f, 0.0f), // bottom left
                glm::vec3(-0.8f, 0.8f, 0.0f), // top left
                }, { 0,1,3,1,2,3, });

        glClearColor(0.3f, 0.2f, 0.0f, 1.0f);
        while (window.isOpen())
        {
                sf::Event event{};
                while (window.pollEvent(event))
                {
                        if (event.type == sf::Event::Closed)
                                window.close();
                }

                glClear(GL_COLOR_BUFFER_BIT);

                shader.Use();
                mesh.Draw();
                window.display();
        }
}
 

2
Feature requests / Adding VertexArray[i].setTexture
« on: April 30, 2021, 07:26:37 pm »
It would be nice if you could set a different texture for every Vertex like you can already do with
color and texCoords.

Now you can only have one texture (repeating grass pattern....) for a whole VertexArray and that is sometimes not enough.

Imagine a map of >1000 province shapes made of VertexArray Triangles.
You have >100 nations, where each nation has a unique color.
Whenever a province is conquered, it changes the color to the new owner.
That is perfectly possible with the current "TriangleVertexArray[k].color = sf::Color......"

But what is if I want to change the texture to a texture specific for the new owner. Let's say owner 1 has a repeating texture of "sand" and owner 2 has a "mountain" texture and so on.
One texture (like in your tile map example) is not enough, because it has to be set to "repeated" and the textures can get pretty big (1-2k resolution).
And making a Vector of >1000 VertexArrays has a very bad performance, even with optimizations like a "culling check", so it is out of question.

How would you solve that problem. I need something like

Pseudo code: (normally a triangle would be the smallest area which makes sense)

if(condition_1)
"TriangleVertexArray[k].setTexture = groundtexture......"
else if(condition_2)
"TriangleVertexArray[k].setTexture = sandtexture......"



3
Graphics / Drawing a class object independently of creation
« on: March 13, 2020, 09:45:30 pm »
Hi,
I'm struggling with drawing a class object, which is to be created during runtime by hitting key A.

Creating is no problem, but how to draw it as it is not created yet. With vectors it's no problem, but how would you handle this case? As I understand it I have to forward declare the object somehow, but how?

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


class UserInterface
{
private:
        sf::Texture uitexture;
        sf::Sprite uisprite;

public:
        UserInterface(std::string loadFromFileString, float x, float y)
        {
                this->uitexture.loadFromFile(loadFromFileString);
                this->uisprite.setTexture(uitexture);
                this->uisprite.setPosition(x, y);
        }

        ~UserInterface()
        {
                std::cout << "deleted" << std::endl;
        }

        void draw(sf::RenderTarget& target)
        {
                target.draw(uisprite);
        }
};


int main()
{
        sf::RenderWindow window(sf::VideoMode(800, 500), "Map", sf::Style::Close);

        while (window.isOpen())
        {
                sf::Event event;
                while (window.pollEvent(event))
                {
                        switch (event.type)
                        {
                        case sf::Event::Closed:
                                window.close();
                                break;
                        case sf::Event::KeyPressed:
                                if (event.key.code == sf::Keyboard::A)
                                {
                                        UserInterface* uio1 = new UserInterface("ui.png", 100, 100);
                                }
                                break;
                        }
                }
               
                window.clear();
                uio1.draw(window);           //   how to draw that?
                window.display();
        }
}


4
General / Color gradient distance calculation for polygons
« on: October 05, 2017, 09:17:06 pm »
Hi people,
finally I've made color gradients for polygons and it works ok,
but the inner point calculation doesn't seem to be right, because the gradients
have a varying width instead of a fixed one. (Width should be more like the black lines are showing)
The outer coordinates are given and the angle bisectors are calculated from them. (calculations are right)
Distance is given with 30 pixels, but that seems to be the problem, because I somehow need a dynamic distance?
The smaller the angle, the longer the distance should be and vice versa....

My formula for calculation of the inner coordinates
(pseudocode for convex shape (concave points--> -distance)):

distance = 30
InnerCoordA(x,y) = OuterCoordA.x+distance*cos(anglebisectorA),OuterCoordA.y+distance*sin(anglebisectorA)

Is there any formula or mathematical concept which could solve my problem? Thx for any help.

5
Hi there,

I'm playing around with textured vertex array triangles and have some questions.

More specifically it's about keeping the same texture resolution independently of the zoom level and with my formula the resolution really stays the same (as intended), but the texture moves around strangely whenever I zoom in or out.

Is there an algorithm to prevent this from happening.
What I need is a solution, where the (endlessly repeated) texture moves with the view while zooming the view.

I know that I have to add an unknown number/calculation to my formula.........
Many thanks in advance for any help!

#include <SFML/Graphics.hpp>

int main()
{
        sf::RenderWindow window(sf::VideoMode(1000,1000), "Map", sf::Style::Close);
        sf::View view(sf::Vector2f(500, 500), sf::Vector2f(1000, 1000));
       
        float zoomvariable = 1;
       
        sf::Texture texture;
        texture.loadFromFile("grass.png");
        texture.setRepeated(true);
       
        sf::VertexArray triangle(sf::Triangles, 3);
        triangle[0].position = sf::Vector2f(0, 0);
        triangle[1].position = sf::Vector2f(900, 0);
        triangle[2].position = sf::Vector2f(600, 900);
        triangle[0].texCoords = sf::Vector2f(triangle[0].position.x,triangle[0].position.y);
        triangle[1].texCoords = sf::Vector2f(triangle[1].position.x,triangle[1].position.y);
        triangle[2].texCoords = sf::Vector2f(triangle[2].position.x,triangle[2].position.y);
       
        while (window.isOpen())
        {
                sf::Event event;
                while (window.pollEvent(event))
                {
                        switch (event.type)
                        {
                        case sf::Event::Closed:
                                window.close();
                                break;
                        case sf::Event::KeyPressed:
                                if(sf::Keyboard::isKeyPressed(sf::Keyboard::Add))
                                {
                                        zoomvariable=zoomvariable*0.9f;
                       
                                        triangle[0].texCoords = sf::Vector2f(triangle[0].position.x/zoomvariable,triangle[0].position.y/zoomvariable);
                                        triangle[1].texCoords = sf::Vector2f(triangle[1].position.x/zoomvariable,triangle[1].position.y/zoomvariable);
                                        triangle[2].texCoords = sf::Vector2f(triangle[2].position.x/zoomvariable,triangle[2].position.y/zoomvariable);
                       
                                        view.zoom(0.9f);
                                }
                                if(sf::Keyboard::isKeyPressed(sf::Keyboard::Subtract))
                                {
                                        zoomvariable=zoomvariable*1.1f;
                       
                                        triangle[0].texCoords = sf::Vector2f(triangle[0].position.x/zoomvariable,triangle[0].position.y/zoomvariable);
                                        triangle[1].texCoords = sf::Vector2f(triangle[1].position.x/zoomvariable,triangle[1].position.y/zoomvariable);
                                        triangle[2].texCoords = sf::Vector2f(triangle[2].position.x/zoomvariable,triangle[2].position.y/zoomvariable);
                       
                                        view.zoom(1.1f);
                                }
                        }
                }
        window.clear();
        window.setView(view);
        window.draw(triangle,&texture);
        window.display();
        }
        return 0;
}


6
Graphics / Changing the color of a part of a sprite
« on: August 19, 2017, 08:32:34 am »
Hi,
is it possible to change the color of a part of a sprite only?
Let's assume that I've got a sprite consisting of a greyscale building and a colored symbol.
How to change the color of the building only (lets say to red), while keeping the original symbol color?

7
Graphics / Color filling algorithm for pseudo-concave shape
« on: July 15, 2017, 01:37:01 pm »
Hi people,

I've got a "pseudo"-concave shape consisting of three triangles.

The question: Is it possible to fill it in a way, that it looks like the right shape (picture attached; right shape filled with paint.net).

Of course, I could draw and use sprites for everything, but they aren't as lightweight as "shapes" and I will need
several thousands of those shapes. Further they can be scaled without quality loss.

Is there any algorithm for the color filling that recognizes the right edges and so on?
Or is it even possible (without using external libraries)? Many thx in advance for any tips!

#include <SFML/Graphics.hpp>

int main()
{

    sf::RenderWindow window(sf::VideoMode(500,500), "Map", sf::Style::Close);
        window.setFramerateLimit(40);
       
        sf::ConvexShape convex;
        convex.setPointCount(3);
        convex.setFillColor(sf::Color(110,150,190,255));
        convex.setPoint(0, sf::Vector2f(170, 350));
        convex.setPoint(1, sf::Vector2f(35, 250));
        convex.setPoint(2, sf::Vector2f(236, 214));
       
        sf::ConvexShape convex2;
        convex2.setPointCount(3);
        convex2.setFillColor(sf::Color(110,150,190,255));
        convex2.setPoint(0, sf::Vector2f(170, 350));
        convex2.setPoint(1, sf::Vector2f(217, 253));
        convex2.setPoint(2, sf::Vector2f(300, 370));
       
       
        sf::ConvexShape convex3;
        convex3.setPointCount(3);
        convex3.setFillColor(sf::Color(110,150,190,255));
        convex3.setPoint(0, sf::Vector2f(170, 350));
        convex3.setPoint(1, sf::Vector2f(300, 370));
        convex3.setPoint(2, sf::Vector2f(156, 417));

        while (window.isOpen())
        {
            sf::Event event;
            while (window.pollEvent(event))
            {
                switch (event.type)
                {
                case sf::Event::Closed:
                    window.close();
                    break;
                        }
                }
       
        window.clear();
        window.draw(convex);
        window.draw(convex2);
        window.draw(convex3);
       
        window.display();
        }
        return 0;
}
 

8
Graphics / Opengl with SFML Walls Render Issue
« on: June 11, 2017, 08:02:05 pm »
Hi people,

I've got a strange problem with the depth buffer (?).
It's similar to: https://en.sfml-dev.org/forums/index.php?topic=20693.msg148603;topicseen#msg148603

I've made a "room" (without ceiling and ground), but the walls are transparent and I don't know why.
I have tried the solution from the link from above, but it didn't work and changing the drawing order didn't either. What I am doing wrong? Many thanks in advance for any help. Sorry that the indentation is wrong, but I don't know how to fix it, because in my compiler it looks ok.

#include <SFML/Graphics.hpp>
#include <iostream>
#define _USE_MATH_DEFINES
#include <math.h>
#include <SFML/OpenGL.hpp>

void myGluPerspective(double fovy, double aspect, double zNear, double zFar)
{
    double f = 1.0 / tan(fovy * M_PI / 360);  // convert degrees to radians and divide by 2
    double xform[16] =
    {
        f / aspect, 0, 0, 0,
        0,          f, 0, 0,
        0,          0, (zFar + zNear)/(zFar - zNear), -1,
        0,          0, 2*zFar*zNear/(zFar - zNear), 0
    };
    glMultMatrixd(xform);
}

int main()
{
        sf::ContextSettings Settings;
        Settings.depthBits = 24;
        Settings.stencilBits = 8;
        Settings.antialiasingLevel = 2;
        sf::Window window(sf::VideoMode(800, 600, 32), "SFML OpenGL", sf::Style::Close, Settings);
       
        window.setFramerateLimit(40);

        glClearDepth(1.f);
        glClearColor(0.8f, 0.8f, 0.8f, 0);

        glEnable(GL_DEPTH_TEST);
        glDepthMask(GL_TRUE);

        glMatrixMode(GL_PROJECTION);
        glLoadIdentity();

        myGluPerspective(60,800/600,0,180);

        glTranslatef(0,0,-3);

    while (window.isOpen())
    {
        sf::Event event;
                while (window.pollEvent(event))
                {
                        switch (event.type)
                        {
                        case sf::Event::Closed:
                                window.close();
                                break;
                        }
                }
               
                window.setActive();
                glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

                glRotatef(1,0,0.5f,0);

                glBegin(GL_QUADS);

                glColor3f(1.0f,1.0f,1.0f);                              // white
                glVertex3f(-1,-1,-1);
                glVertex3f(1,-1,-1);
                glVertex3f(1,1,-1);
                glVertex3f(-1,1,-1);

                glColor3f(0.0f,1.0f,0.0f);                              // green
                glVertex3f(-1,1,1);
                glVertex3f(-1,-1,1);
                glVertex3f(-1,-1,-1);
                glVertex3f(-1,1,-1);

                glColor3f(0.0f,0.0f,1.0f);                              // blue
                glVertex3f(1,1,1);
                glVertex3f(1,-1,1);
                glVertex3f(1,-1,-1);
                glVertex3f(1,1,-1);

                glColor3f(0.0f,1.0f,1.0f);                              // cyan
                glVertex3f(-1,-1,1);
                glVertex3f(1,-1,1);
                glVertex3f(1,1,1);
                glVertex3f(-1,1,1);

                glEnd();

        window.display();
    }

    return 0;
}
 

9
Graphics / Animating Sprites with different numbers of frames efficiently.
« on: September 08, 2016, 08:19:47 pm »
Hi guys,
my question is about how to animate sprites with different numbers of frames efficiently. (in one loop and with less variables than in my example)
Let's say I've got object1 (300x100 pixels) with 3 frames and object2 (400*100 pixels) with 4 frames.
The animation should work as follows: (go 1 frame forward per second until end an then start over again)
object 1: 1 2 3 1 2 3 1 2 3 1 2 3....
object 2: 1 2 3 4 1 2 3 4 1 2 3 4....
Is it possible to rewrite the code, that I won't need multiple clocks and so many variables for it to work properly.

#include <SFML/Graphics.hpp>

int main()
{
        std::vector<sf::Sprite> AnimatedObjectsVector;

        sf::Texture textureanim;
        textureanim.loadFromFile("object1.png");
        sf::Sprite spriteanim(textureanim);
        spriteanim.setPosition(200,200);
        AnimatedObjectsVector.push_back(spriteanim);

        sf::Texture textureanim2;
        textureanim2.loadFromFile("object2.png");
        sf::Sprite spriteanim2(textureanim2);
        spriteanim2.setPosition(300,200);
        AnimatedObjectsVector.push_back(spriteanim2);

    sf::RenderWindow window(sf::VideoMode(1200,900), "Map", sf::Style::Close);                 
        window.setFramerateLimit(30);
       
        sf::Time time;
        sf::Clock clock;
        sf::Clock clock2;

    while (window.isOpen())
    {
        sf::Event event;

                while (window.pollEvent(event))
                {
                        switch (event.type)
                        {
                        case sf::Event::Closed:
                                window.close();
                                break;
                        }
                }

                int sec  = clock.getElapsedTime().asSeconds();
                int sec2 = clock2.getElapsedTime().asSeconds();
                int animator = sec*100;
                int animator2 = sec2*100;
                                                                               
                if(animator>200)
                {
                        animator = 0;
                        clock.restart();
                }

                if(animator2>300)
                {
                        animator2 = 0;
                        clock2.restart();
                }

                for (auto& it = AnimatedObjectsVector.begin(); it != AnimatedObjectsVector.end(); ++it)
                {
                        if(it->getTexture()==&textureanim)
                        {
                                it->setTextureRect(sf::IntRect(animator, 0, 100, 100));
                        }
                        if(it->getTexture()==&textureanim2)
                        {
                                it->setTextureRect(sf::IntRect(animator2, 0, 100, 100));
                        }
                }
                window.clear();
                for (auto& it = AnimatedObjectsVector.rbegin(); it != AnimatedObjectsVector.rend(); ++it)
               {
                        window.draw(*it);
               }
               window.display();
       }
       return 0;
}
 

10
Graphics / Loading huge amount of images
« on: May 05, 2015, 07:19:56 am »
I need to load a very high amount of 1000*1000 pixel images (40000*20000 pixel "world map") and would like to ask, if the image loading code can be written in a shorter way:

        sf::Image mapimage1;
        mapimage1.loadFromFile("mapimage1.png");
        sf::Texture maptexture1;
        maptexture1.loadFromImage(mapimage1);
        sf::Sprite mapsprite1(maptexture1);
        mapsprite1.setPosition(0, 0);

       ............

        sf::Image mapimage800;
        mapimage800.loadFromFile("mapimage800.png");
        sf::Texture maptexture800;
        maptexture800.loadFromImage(mapimage800);
        sf::Sprite mapsprite800(maptexture800);
        mapsprite1.setPosition(39000, 19000);

The images represent a "province map", where every province has a unique rgb color
and I need those images only to get the pixelcolor for finding out which province was clicked.
With this, there is another problem. For finding out, where the cursor is, I need 800 if conditions like the following one:

                        if(mapsprite1.getGlobalBounds().contains(coord_pos.x,coord_pos.y))
                        {
                                color = mapimage1.getPixel(coord_pos.x, coord_pos.y);
                        }

                        ..................

                        else if(mapsprite800.getGlobalBounds().contains(coord_pos.x,coord_pos.y))
                        {
                                color = mapimage800.getPixel(coord_pos.x, coord_pos.y);
                        }


Is there a way to make the code shorter, because that would be overkill needing many thousand lines of code only for those simple operations?

11
Graphics / Wrapping map view visibility issues in sfml
« on: April 20, 2015, 07:44:11 am »
I'm opening a new question, because it's about a different problem, where a view is completely invisible.
I'm implementing a wrapping map consisting of two neighbouring parts. The problem: Only the first view is visible and works as intended. The second view is invisible and I don't know why. If you go to the left, there is a a black area instead of the second view. After having done many number changes/tests, it seems as the second view is limited to the area of the first view only. I´ve really tried to change everything, I`ve read many old posts and the view tutorials, but it is a "mission impossible". With one tiled maps, that were not bigger than the screen size it worked like a charm, unlike here. Many thanks for any help in advance.

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

int main()
{
    sf::RenderWindow mMainWindow(sf::VideoMode(1000,600), "Map", sf::Style::Close);
    sf::View view(sf::Vector2f(500, 300), sf::Vector2f(1000, 600));
    sf::View view2(sf::Vector2f(500, 300), sf::Vector2f(1000, 600));

    sf::Image mapimage;
    mapimage.loadFromFile("world1.jpg");  //1000*600 px
    sf::Texture maptexture;
    maptexture.loadFromImage(mapimage);
    sf::Sprite mapsprite(maptexture);
    sf::Sprite mapsprite2(maptexture);
    mapsprite.setPosition(0, 0);
    mapsprite2.setPosition(1000, 0);

    sf::RectangleShape viewrect;
    viewrect.setSize(sf::Vector2f(2000, 600));
    viewrect.setPosition(0, 0);
    viewrect.setFillColor(sf::Color(250,0,0,40));

    sf::RectangleShape viewrect2;
    viewrect2.setSize(sf::Vector2f(2000, 600));
    viewrect2.setPosition(0, 0);
    viewrect2.setFillColor(sf::Color(0,0,250,40));

    float fview2 = 1;
    view2.setViewport(sf::FloatRect(fview2, 0, 1, 1));
    int mapmovementvar = 0;

    while (mMainWindow.isOpen())
    {
        sf::Event event;

        while (mMainWindow.pollEvent(event))
        {
            switch (event.type)
            {
            case sf::Event::Closed:
                mMainWindow.close();
                break;
            }
        }
        if(sf::Keyboard::isKeyPressed(sf::Keyboard::Left))
        {
            system("cls");
            view.move(-100, 0);
            fview2=fview2+0.1f;
            mapmovementvar--;

            if(mapmovementvar<0)
            {  
                mapmovementvar=19;
                fview2=-0.9f;
                view.reset(sf::FloatRect(1900, 0, 1000, 600));
                view2.reset(sf::FloatRect(-1000, 0, 1000, 600));
            }

            view2.setViewport(sf::FloatRect(fview2, 0, 1, 1));
            std::cout << "fview2 " << fview2 << std::endl;
            std::cout << "mapmovementvar " << mapmovementvar << std::endl;
        }

        mMainWindow.clear();

        mMainWindow.setView(view);
        mMainWindow.draw(mapsprite);
        mMainWindow.draw(mapsprite2);
        mMainWindow.draw(viewrect);

        mMainWindow.setView(view2);
        mMainWindow.draw(mapsprite);
        mMainWindow.draw(mapsprite2);
        mMainWindow.draw(viewrect2);

        mMainWindow.display();
    }
    return 0;
}

12
Graphics / Wrapping world view movement glitch
« on: April 18, 2015, 02:50:17 pm »
Hi,

I'm working on a wrapping world functionality. So far it works. But only after having moved to the left, so the "left keyboard key is pressed if condition: if(fview2>=1)" is activated at least once with the consequence that everything works perfectly forever.
But if I go only to the right and the condition as mentioned is never activated, the view becomes somehow distorted after going too far to the right. Only after having activated the "left if condition" at least once, the distortion gets away and everything is fine forever. I really don't know whats wrong. Maybe it has something to do with the fact, that the fview2 value changes to strange numbers under certain conditions when it shouldn't have (f.e. 0.09999999 instead of 0.1 or -7.30157e-008 instead of 0). Did I encounter an sfml bug?
Many thanks in advance.

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

int main()
{
    sf::RenderWindow mMainWindow(sf::VideoMode(1000,600), "Map", sf::Style::Close);
        sf::View view(sf::Vector2f(500, 300), sf::Vector2f(1000, 600));
        sf::View view2(sf::Vector2f(500, 300), sf::Vector2f(1000, 600));

    mMainWindow.setFramerateLimit(60);

        sf::Image mapimage;
        mapimage.loadFromFile("world1.jpg");  //1000*600 px
        sf::Texture maptexture;
        maptexture.loadFromImage(mapimage);
        sf::Sprite mapsprite(maptexture);
        mapsprite.setPosition(0, 0);

        sf::RectangleShape viewrect;
        viewrect.setSize(sf::Vector2f(1000, 600));
        viewrect.setPosition(0, 0);
        viewrect.setFillColor(sf::Color(250,0,0,40));

        sf::RectangleShape viewrect2;
        viewrect2.setSize(sf::Vector2f(1000, 600));
        viewrect2.setPosition(0, 0);
        viewrect2.setFillColor(sf::Color(0,0,250,40));

        float fview2 = 1;
        view2.setViewport(sf::FloatRect(fview2, 0, 1, 1));

    while (mMainWindow.isOpen())
    {
        sf::Event event;

        while (mMainWindow.pollEvent(event))
        {
            switch (event.type)
            {
            case sf::Event::Closed:
                mMainWindow.close();
                break;
            }
                }
                if(sf::Keyboard::isKeyPressed(sf::Keyboard::Left))
                {
                        system("cls");
                        view.move(-100, 0);
                        fview2=fview2+0.1f;

                        if(fview2>=1)
                        {      
                                fview2=0;
                                view.reset(sf::FloatRect(900, 0, 1000, 600));
                                view2.reset(sf::FloatRect(-100, 0, 1000, 600));
                        }

                        view2.setViewport(sf::FloatRect(fview2, 0, 1, 1));
                        std::cout << "fview2 " << fview2 << std::endl;
                }
                if(sf::Keyboard::isKeyPressed(sf::Keyboard::Right))
                {
                        system("cls");
                        view.move(100, 0);
                        fview2=fview2-0.1f;

                        if(fview2<-0.09)
                        {
                                fview2=0.9f;
                                view.reset(sf::FloatRect(0, 0, 1000, 600));
                        }
                        view2.setViewport(sf::FloatRect(fview2, 0, 1, 1));
                        std::cout << "fview2 " << fview2 << std::endl;
                }

        mMainWindow.clear();

                mMainWindow.setView(view);
                mMainWindow.draw(mapsprite);
                mMainWindow.draw(viewrect);

                mMainWindow.setView(view2);
                mMainWindow.draw(mapsprite);
                mMainWindow.draw(viewrect2);

        mMainWindow.display();
    }
    return 0;
}

13
Window / Correct mouse coordinates with multiple views.
« on: April 15, 2015, 06:12:49 pm »
Hi there,

is there a way to print the correct map coordinates while using multiple views? Now it only shows the coordinates in relation to the left view, even when I click into the right view. For example if I click into the top left corner of the left view it should show the same coordinates as clicking into the top left corner of the right view. How to do that?

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

int main()
{
    sf::RenderWindow mMainWindow(sf::VideoMode(1000,600), "Map", sf::Style::Close);
        sf::View view(sf::Vector2f(500, 300), sf::Vector2f(1000, 600));
        sf::View view2(sf::Vector2f(500, 300), sf::Vector2f(1000, 600));
        view.setViewport(sf::FloatRect(0, 0, 0.5f, 1));
        view2.setViewport(sf::FloatRect(0.5f, 0, 0.5f, 1));
       
    mMainWindow.setFramerateLimit(60);
    mMainWindow.setKeyRepeatEnabled(false);

        sf::Image mapimage;
        mapimage.loadFromFile("world1.jpg");
        sf::Texture maptexture;
        maptexture.loadFromImage(mapimage);
        sf::Sprite mapsprite(maptexture);
        mapsprite.setPosition(0, 0);

    while (mMainWindow.isOpen())
    {
        sf::Event event;
        sf::Vector2i mousePos;
                bool leftclicked = false;

        while (mMainWindow.pollEvent(event))
        {
            switch (event.type)
            {
            case sf::Event::Closed:
                mMainWindow.close();
                break;
                        case sf::Event::MouseButtonPressed:
                if (event.mouseButton.button == sf::Mouse::Left)
                                {
                    leftclicked = true;
                                        sf::Vector2i pixel_pos = sf::Mouse::getPosition(mMainWindow);
                                        sf::Vector2f coord_pos = mMainWindow.mapPixelToCoords(pixel_pos);
                                       
                                        std::cout << coord_pos.x << std::endl;
                                        std::cout << coord_pos.y << std::endl;
                                        break;
                                }
         
                               
            }
        }


        mMainWindow.clear();
                mMainWindow.setView(view2);
                mMainWindow.draw(mapsprite);
                mMainWindow.setView(view);
                mMainWindow.draw(mapsprite);
        mMainWindow.display();
    }
    return 0;
}

14
Graphics / Moving sprites to target position.
« on: March 05, 2015, 07:37:11 pm »
Hi there, I hope you can help me with this, because I don't know what's wrong with the code.
There are some strange moves going on and you have to click more than once on it to move to target.
I would like to move sprites around: Focus a sprite by left-click and then hit left mouse button again somewhere on the map to move it to that position. After this is done, the focus should be removed from the sprite. Thx in advance.

#include <SFML/Graphics.hpp>
#include <iostream>
#include <vector>

int main()
{
    sf::RenderWindow mMainWindow(sf::VideoMode(600,600), "Map", sf::Style::Close);
    mMainWindow.setFramerateLimit(60);
    mMainWindow.setKeyRepeatEnabled(false);
    sf::Image image;
    image.create(50, 50, sf::Color::Red);
    sf::Texture texture;
    texture.loadFromImage(image);

    std::vector<sf::Sprite> EnemyVector;
        std::vector<sf::Vector2f> EnemyPositions;
        std::vector<sf::Vector2f> EnemyDestinations;

        sf::Sprite* focus = nullptr;
        bool move = false;
       
    while (mMainWindow.isOpen())
    {
        sf::Event event;
        bool creating = false;
        bool leftclicked = false;
        sf::Vector2i mousePos;

        while (mMainWindow.pollEvent(event))
        {
            switch (event.type)
            {
            case sf::Event::Closed:
                mMainWindow.close();
                break;
            case sf::Event::KeyPressed:
                creating = (event.key.code == sf::Keyboard::A);
                break;
            case sf::Event::MouseButtonPressed:
                if (event.mouseButton.button == sf::Mouse::Left)
                                {
                    leftclicked = true;
                                        mousePos = sf::Vector2i(event.mouseButton.x, event.mouseButton.y);
                                        break;
                                }
            }
        }
        if (creating)
        {
            sf::Sprite sprite;
            mousePos = (mousePos == sf::Vector2i(0, 0) ? sf::Mouse::getPosition(mMainWindow) : mousePos);
            sprite.setTexture(texture);
            sprite.setColor(sf::Color::Red);
            sprite.setOrigin(static_cast<float>(sprite.getTextureRect().width) / 2, static_cast<float>(sprite.getTextureRect().height) / 2);
            sprite.setPosition(static_cast<float>(mousePos.x), static_cast<float>(mousePos.y));
                        focus=nullptr;
            EnemyVector.push_back(sprite);
                        EnemyPositions.push_back(sf::Vector2f(static_cast<float>(mousePos.x), static_cast<float>(mousePos.y)));
                        EnemyDestinations.push_back(sf::Vector2f(static_cast<float>(mousePos.x), static_cast<float>(mousePos.y)));
        }
                if (leftclicked)
                {
                        for (auto& enemy = EnemyVector.rbegin(); enemy != EnemyVector.rend(); ++enemy)
                        {
                                if (enemy->getGlobalBounds().contains(static_cast<float>(mousePos.x), static_cast<float>(mousePos.y)))
                                {
                                        focus = &(*enemy);
                                       
                                }
                                else
                                {
                                        EnemyDestinations[std::distance(EnemyVector.rbegin(),enemy)].x = static_cast<float>(mousePos.x);
                                        EnemyDestinations[std::distance(EnemyVector.rbegin(),enemy)].y = static_cast<float>(mousePos.y);
                                        move=!move;    
                                }
                        }
                }
                if(move)
                {
                        for (auto& enemy = EnemyVector.rbegin(); enemy != EnemyVector.rend(); ++enemy)
                        {
                                if(focus!=nullptr)
                                {
                                        focus->move((EnemyDestinations[std::distance(EnemyVector.rbegin(),enemy)].x - focus->getPosition().x)*0.1,(EnemyDestinations[std::distance(EnemyVector.rbegin(),enemy)].y - focus->getPosition().y)*0.1);
                               
                                }
                        }
                }
        mMainWindow.clear();
        for (auto& enemy = EnemyVector.rbegin(); enemy != EnemyVector.rend(); ++enemy)
        {
            mMainWindow.draw(*enemy);
        }
        mMainWindow.display();
    }
    return 0;
}
 

15
Graphics / Counting sprites of specific type in vector
« on: February 28, 2015, 08:27:26 pm »
Hi,

is there a way to count sprites (of specific type) in a vector?

The following code doesn't work and I don't know why? Many thanks in advance for any help.

            int mycount = std::count (EnemyVector.begin(), EnemyVector.end(), sprite);
            std::cout << "number of red squares: " << mycount  << std::endl;

#include <SFML/Graphics.hpp>
#include <iostream>
#include <vector>
#include <algorithm>

int main()
{
    sf::RenderWindow mMainWindow(sf::VideoMode(600,600), "Map", sf::Style::Close);
    mMainWindow.setFramerateLimit(60);
    mMainWindow.setKeyRepeatEnabled(false);

        sf::Image image;
    image.create(50, 50, sf::Color::Red);
        sf::Texture texture;
        texture.loadFromImage(image);

    std::vector<sf::Sprite> EnemyVector;

    while (mMainWindow.isOpen())
    {
        sf::Event event;

        bool creating = false;
                bool rightclick = false;
       
        sf::Vector2i mousePos;

        while (mMainWindow.pollEvent(event))
        {
            switch (event.type)
            {
            case sf::Event::Closed:
                mMainWindow.close();
                break;
            case sf::Event::KeyPressed:
                                if (event.key.code == sf::Keyboard::A)
                                {
                                        creating = true;
                                        break;
                                }
            case sf::Event::MouseButtonPressed:
                                if (event.mouseButton.button == sf::Mouse::Right)
                                {
                                        rightclick = true;
                                        mousePos = sf::Vector2i (event.mouseButton.x, event.mouseButton.y);
                                        break;
                                }
                break;
            }
                }
        if (creating)
        {
            sf::Sprite sprite;
            mousePos = (mousePos == sf::Vector2i(0, 0) ? sf::Mouse::getPosition(mMainWindow) : mousePos);
                        sprite.setTexture(texture);

            sprite.setOrigin(static_cast<float>(sprite.getTextureRect().width) / 2, static_cast<float>(sprite.getTextureRect().height) / 2);
            sprite.setPosition(static_cast<float>(mousePos.x), static_cast<float>(mousePos.y));
            EnemyVector.push_back(sprite);

                        int mycount = std::count (EnemyVector.begin(), EnemyVector.end(), sprite);
                        std::cout << "number of red squares: " << mycount  << std::endl;
                }
                if (rightclick)
                {
                        for (auto& SpriteIt = EnemyVector.rbegin(); SpriteIt != EnemyVector.rend(); ++SpriteIt)
            {
                sf::Vector2f mousecoords(mMainWindow.mapPixelToCoords(sf::Vector2i(event.mouseButton.x, event.mouseButton.y)));
                if (SpriteIt->getGlobalBounds().contains(mousecoords))
                                {
                                        EnemyVector.erase( std::next(SpriteIt).base() );

                                        sf::Sprite sprite;
                                        int mycount = std::count (EnemyVector.begin(), EnemyVector.end(), sprite);
                                        std::cout << "number of red squares: " << mycount  << std::endl;
                                        break;
                                }
            }
        }

        mMainWindow.clear();
        for (auto& enemy = EnemyVector.begin(); enemy != EnemyVector.end(); ++enemy)
        {
            mMainWindow.draw(*enemy);
        }
        mMainWindow.display();
    }
    return 0;
}
 

Pages: [1] 2
anything