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

Author Topic: [SOLVED!] Only one fourth of the buffer displays in the SFML window?!  (Read 814 times)

0 Members and 1 Guest are viewing this topic.

KKZiomekkk

  • Newbie
  • *
  • Posts: 6
    • View Profile
    • Email
Hello, I recently was making a Mandelbrot Fractal viewer, and I came upon a very weird problem. Only one fourth of the buffer loads, more specifically the top-right fourth of the screen. This is the code (The SFML window is in InitState.cpp and the Bitmap with pixel-buffer is used in files InitState.hpp/cpp and Fractal.hpp/cpp):

main.cpp:
#include "ProgramEngine.hpp"
#include "ProgramState.hpp"
#include "InitState.hpp"

int main(int argc, char** argv)
{
        ProgramEngine program;
        InitState initState;

        program.init();
        program.changeState(&initState);

        while (program.isRunning())
        {
                program.handleEvents();
                program.update();
                program.draw();
        }

        program.cleanUp();

        return 0;
}

ProgramEngine.hpp:
#ifndef PROGRAM_ENGINE_HPP
#define PROGRAM_ENGINE_HPP

#include <vector>

class ProgramState;

class ProgramEngine
{
public:

        void init();
        void cleanUp();

        void changeState(ProgramState* state);
        void pushState(ProgramState* state);
        void popState();

        void handleEvents();
        void update();
        void draw();

        bool isRunning();
        void quit();

        std::vector<ProgramState*> states;

        bool running;
};

#endif

ProgramEngine.cpp:
#include "ProgramEngine.hpp"
#include "ProgramState.hpp"

void ProgramEngine::init()
{
        running = true;
}

void ProgramEngine::cleanUp()
{
        for (std::vector<ProgramState*>::iterator i = states.begin(); i != states.end(); i++)
        {
                (*i)->cleanUp();
        }
        states.clear();
}

void ProgramEngine::changeState(ProgramState* state)
{
        for (std::vector<ProgramState*>::iterator i = states.begin(); i != states.end(); i++)
        {
                (*i)->cleanUp();
        }
        states.clear();

        states.push_back(state);
        state->init();
}

void ProgramEngine::pushState(ProgramState* state)
{
        states.push_back(state);
        state->init();
}

void ProgramEngine::popState()
{
        states.back()->cleanUp();
        states.pop_back();
}

void ProgramEngine::handleEvents()
{
        for (std::vector<ProgramState*>::iterator i = states.begin(); i != states.end(); i++)
        {
                (*i)->handleEvents(this);
        }
}

void ProgramEngine::update()
{
        for (std::vector<ProgramState*>::iterator i = states.begin(); i != states.end(); i++)
        {
                (*i)->update(this);
        }
}

void ProgramEngine::draw()
{
        for (std::vector<ProgramState*>::iterator i = states.begin(); i != states.end(); i++)
        {
                (*i)->draw(this);
        }
}

bool ProgramEngine::isRunning()
{
        return running;
}

void ProgramEngine::quit()
{
        running = false;
}

ProgramState.hpp:
#ifndef PROGRAM_STATE_HPP
#define PROGRAM_STATE_HPP

class ProgramEngine;

class ProgramState
{
public:

        virtual void init() = 0;
        virtual void cleanUp() = 0;

        virtual void pause() = 0;
        virtual void resume() = 0;

        virtual void handleEvents(ProgramEngine* program) = 0;
        virtual void update(ProgramEngine* program) = 0;
        virtual void draw(ProgramEngine* program) = 0;

        void changeState(ProgramEngine* program, ProgramState* state);
};

#endif

ProgramState.cpp:
#include "ProgramEngine.hpp"
#include "ProgramState.hpp"

void ProgramState::changeState(ProgramEngine* program, ProgramState* state)
{
        program->changeState(state);
}

InitState.hpp:
#ifndef INIT_STATE_HPP
#define INIT_STATE_HPP

#include <SFML\System.hpp>
#include <SFML\Window.hpp>
#include <SFML\Graphics.hpp>
#include <SFML\OpenGL.hpp>

#include "ProgramEngine.hpp"
#include "ProgramState.hpp"
#include "Fractal.hpp"

class Bitmap;

class InitState :public ProgramState
{
public:

        void init();
        void cleanUp();
       
        void pause();
        void resume();

        void handleEvents(ProgramEngine* program);
        void update(ProgramEngine* program);
        void draw(ProgramEngine* program);

private:

        sf::RenderWindow* window;
        sf::Clock* clock;

        Bitmap* bitmap;

        long previousTime;
        double delta;

        Fractal* mandelbrot;
};

#endif

InitState.cpp:
#include "InitState.hpp"
#include "Preprocessor.hpp"

#include "Bitmap.h"

void InitState::init()
{
        window = new sf::RenderWindow(sf::VideoMode(800, 600, 32U), "Test");
        bitmap = new Bitmap(800, 600);
        clock = new sf::Clock();
        mandelbrot = new Fractal(bitmap, sf::Vector2u(800, 600));

        glEnable(GL_TEXTURE_2D);

        previousTime = clock->getElapsedTime().asMicroseconds();
        srand(time(NULL));

        window->setActive(false);
}

void InitState::cleanUp()
{
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

        delete window;
        delete clock;
        delete bitmap;
        delete mandelbrot;
}

void InitState::pause()
{

}

void InitState::resume()
{

}

void InitState::handleEvents(ProgramEngine* program)
{
        sf::Event event;
        while (window->pollEvent(event))
        {
                switch (event.type)
                {
                case sf::Event::Closed:
                        program->quit();
                        break;
                }
        }
}

void InitState::update(ProgramEngine* program)
{
        long currentTime = clock->getElapsedTime().asMicroseconds();
        delta = (currentTime - previousTime) / 1000000.0;
        previousTime = currentTime;
}

void InitState::draw(ProgramEngine* program)
{
        window->setActive(true);

        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
        bitmap->clear(0x000000ff);

        mandelbrot->compute();

        bitmap->displayPixels();
        window->display();

        window->setActive(false);
}

Fractal.hpp:
#ifndef FRACTAL_HPP
#define FRACTAL_HPP

#include <SFML\System.hpp>
#include <SFML\Window.hpp>
#include <SFML\Graphics.hpp>
#include <SFML\OpenGL.hpp>

class Bitmap;

class Fractal
{
public:

        Fractal(Bitmap* _bitmap, sf::Vector2u fractal_size);

        void compute();

private:

        sf::Vector2i getOriginPixel(sf::Vector2u window_size);

private:

        Bitmap* bitmap;

        sf::Vector2u size;
        sf::Vector2f position;

        double leftBound;
        double rightBound;
        double sizeUnits;
        double pixelSize;

        double zoom;
        double prevZoom;

        int iterations;
};

#endif

Fractal.cpp:
#include "Fractal.hpp"
#include "Bitmap.h"

#include <cmath>

Fractal::Fractal(Bitmap* _bitmap, sf::Vector2u fractal_size)
{
        bitmap = _bitmap;

        size = fractal_size;

        leftBound = -2.5;
        rightBound = 1.5;
        sizeUnits = abs(leftBound - rightBound);

        position = sf::Vector2f((leftBound + rightBound)/2, 0);
        zoom = 1.0;

        iterations = 256;
}

void Fractal::compute()
{
        for (unsigned int pixelY = 1; pixelY <= size.y; pixelY++)
        {
                for (unsigned int pixelX = 1; pixelX <= size.x; pixelX++)
                {
                        pixelSize = (sizeUnits / (double)(size.x)) / zoom;
                        double a = ((double)(pixelX - getOriginPixel(size).x) * pixelSize) + (double)(position.x);
                        double b = ((double)(getOriginPixel(size).y - pixelY) * pixelSize) + (double)(position.y);

                        double xtemp = 0;
                        double x = 0;
                        double y = 0;

                        int i;

                        for (i = 1; (i <= iterations) && ((x*x + y*y) < 4); i++)
                        {
                                xtemp = pow(x, 2) - pow(y, 2) + a;
                                y = 2 * x*y + b;
                                x = xtemp;

                                //xtemp = pow(x, 6) - 15 * pow(x, 4)*pow(y, 2) + 15 * pow(x, 2)*pow(y, 4) - pow(y, 6) + a;
                                //y = 6 * pow(x, 5)*y - 20 * pow(x, 3)*pow(y, 3) + 6 * x*pow(y, 5) + b;
                                //x = xtemp;
                        }

                        if (i == iterations)
                        {
                                bitmap->drawPixel(pixelX, pixelY, 0x00, 0x00, 0x00, 0xff);
                        }
                        if (i < iterations)
                        {
                                unsigned char colorlinear = ((i * 0xff) / (iterations / (iterations / 64))) % 0x100;

                                bitmap->drawPixel(pixelX, pixelY, round(colorlinear / 2), colorlinear, 0x00, 0xff);
                        }
                }
        }
}

sf::Vector2i Fractal::getOriginPixel(sf::Vector2u window_size)
{
        sf::Vector2i origin(ceil(window_size.x / 2), ceil(window_size.y / 2));

        return origin;
}

Bitmap.h:
#ifndef SFML_OPENGL_BITMAP_H
#define SFML_OPENGL_BITMAP_H

class Bitmap
{
public:

        Bitmap(int width, int height) //Konstruktor klasy Bitmap
        :buffer_width(width), buffer_height(height)
        {
                buffer = new unsigned char [height*(4 * width)];
        }

        void clear(const unsigned int& colorRGBA) //Czyszczenie buffera bitmapy wybranym kolorem RGBA
        {
                unsigned char r = (colorRGBA & 0xff000000) >> 24;
                unsigned char g = (colorRGBA & 0x00ff0000) >> 16;
                unsigned char b = (colorRGBA & 0x0000ff00) >> 8;
                unsigned char a = (colorRGBA & 0x000000ff) >> 0;

                for (int y = 0; y < buffer_height; y++)
                {
                        for (int x = 0; x < buffer_width; x++)
                        {
                                buffer[y*(buffer_width * 4) + (x * 4) + 0] = r;
                                buffer[y*(buffer_width * 4) + (x * 4) + 1] = g;
                                buffer[y*(buffer_width * 4) + (x * 4) + 2] = b;
                                buffer[y*(buffer_width * 4) + (x * 4) + 3] = a;
                        }
                }
        }

        void clear(const unsigned char& r, const unsigned char& g, const unsigned char& b, const unsigned char& a = 0xff)
                //Czyszczenie buffera bitmapy wybranym kolorem RGBA, rozpisane argument po argumencie
        {
                for (int y = 0; y < buffer_height; y++)
                {
                        for (int x = 0; x < buffer_width; x++)
                        {
                                buffer[y*(buffer_width * 4) + (x * 4) + 0] = r;
                                buffer[y*(buffer_width * 4) + (x * 4) + 1] = g;
                                buffer[y*(buffer_width * 4) + (x * 4) + 2] = b;
                                buffer[y*(buffer_width * 4) + (x * 4) + 3] = a;
                        }
                }
        }

        void clearGray(const unsigned char& grayscale) //Czyszczenie buffera bitmapy wybranym odcieniem szaro&#347;ci
        {
                for (int y = 0; y < buffer_height; y++)
                {
                        for (int x = 0; x < buffer_width; x++)
                        {
                                buffer[y*(buffer_width * 4) + (x * 4) + 0] = grayscale;
                                buffer[y*(buffer_width * 4) + (x * 4) + 1] = grayscale;
                                buffer[y*(buffer_width * 4) + (x * 4) + 2] = grayscale;
                                buffer[y*(buffer_width * 4) + (x * 4) + 3] = 0xff;
                        }
                }
        }

        void drawPixel(int x, int y, const unsigned int& colorRGBA) //Rysowanie piksela na ekranie
        {
                unsigned char r = (colorRGBA & 0xff000000) >> 24;
                unsigned char g = (colorRGBA & 0x00ff0000) >> 16;
                unsigned char b = (colorRGBA & 0x0000ff00) >> 8;
                unsigned char a = (colorRGBA & 0x000000ff) >> 0;

                if (x >= buffer_width) { x = buffer_width - 1; }
                if (y >= buffer_height) { y = buffer_height - 1; }
                if (x <= 0) { x = 0; }
                if (y <= 0) { y = 0; }

                y = buffer_height - y - 1;

                buffer[y*(buffer_width * 4) + (x * 4) + 0] = r;
                buffer[y*(buffer_width * 4) + (x * 4) + 1] = g;
                buffer[y*(buffer_width * 4) + (x * 4) + 2] = b;
                buffer[y*(buffer_width * 4) + (x * 4) + 3] = a;
        }

        void drawPixel(int x, int y, const unsigned char& r, const unsigned char& g,
                const unsigned char& b, const unsigned char& a = 0xff) //Rysowanie piksela na ekranie
        {
                if (x >= buffer_width) { x = buffer_width - 1; }
                if (y >= buffer_height) { y = buffer_height - 1; }
                if (x <= 0) { x = 0; }
                if (y <= 0) { y = 0; }

                y = buffer_height - y - 1;

                buffer[y*(buffer_width * 4) + (x * 4) + 0] = r;
                buffer[y*(buffer_width * 4) + (x * 4) + 1] = g;
                buffer[y*(buffer_width * 4) + (x * 4) + 2] = b;
                buffer[y*(buffer_width * 4) + (x * 4) + 3] = a;
        }

        void displayPixels() //Kopiowanie buffera bitmapy do buffera OpenGL
        {
                glDrawPixels(buffer_width, buffer_height, GL_RGBA, GL_UNSIGNED_BYTE, buffer);
        }

public:

        int buffer_width;
        int buffer_height;

private:

        unsigned char* buffer;

}; //END OF: class Bitmap

#endif

Thank you for help!
« Last Edit: October 17, 2017, 02:36:52 am by KKZiomekkk »

KKZiomekkk

  • Newbie
  • *
  • Posts: 6
    • View Profile
    • Email
Re: [SOLVED!] Only one fourth of the buffer displays in the SFML window?!
« Reply #1 on: October 17, 2017, 02:36:40 am »
I solved the problem. In Fractal.cpp in void Fractal::compute() at the main double-for loop, the iterator type was supposed to be int instead of unsigned int. When it was unsigned int it ruined the calculations because negative numbers were changed to very big positive numbers and at the end the pixel coordinates of the remaining three quarters of the screen were ridiculously high, and when opengl tried to draw the buffer, it failed miserably.

Peace!
« Last Edit: October 17, 2017, 02:38:25 am by KKZiomekkk »