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.


Messages - Critkeeper

Pages: 1 [2] 3 4 5
16
Texture and Shader are already both loadable members of RenderStates

It would be fairly trivial to store and load BlendMode and Transform, given how simplistic they are.

And that would allow us to make RenderStates a loadable resource.



If we also made Drawable a loadable resource then resource management would become so much simpler for the client. You could load up a drawable and renderStates and just tell the renderWindow to draw it.

idk, just seems like it would be easier to use for me personally. That doesn't mean its the right way to go, but I'm interested in hearing your thoughts.

17
I really don't have any suggestions. I'm just trying to get everyone talking about composition as an approach to multimedia libraries, particularly SFML, and what the drawbacks and advantages are of doing it that way. If there were many more media available to us through multimedia libraries then composition is obviously the only sane choice because of combinatorial explosion-- but there are only 3 media available to us really, so it behooves us to inspect our own assumptions about what is "sane" and what isn't.

18
This is a controversial question that is intended to stir up a discussion about what SFML actually is, not an actual feature request.

Lets define what a media is. I believe media is any data that can be consumed by a human. For example, music is media because it can be parsed by a human, and visual art is a media. Sculpture is a form of visual art and is its own kind of media if you are permitted to touch it. Naively , since humans only have 6 senses through which to experience the world, sight, smell, taste, touch, hearing and time, media can be broken up into 6 categories.

But human experience is wider than the 6 physical sensations! There are internal sensations, like love and hate. So then it would be more precise to say that there are 2 classes of media, physical and nonphysical, and 6 classes of physical media. Mutimedia just means multiple mediums at once, for example a movie is multimedia. In fact, art can be multimedia if it causes you to feel something nonphysical, like wistfulness.

Naturally it is not possible to cause a person to feel an emotion without exposing them to some kind of physical stimuli. Therefore, all arts that can be classified as nonphysical media are also physical media as a matter of course.

This brings me to SFML, which stands for simple fast multimedia library. Media here obviously refers to physical media. With the current state of the art there are barely over 3 physical media that can be conveyed through the computer-- sight and sound and time obviously, and perhaps a limited tactile experience through vibrating rumble controllers or touch screens. So our ability to convey nonphysical media is restricted to what we can invoke through half of the human physical senses!

Despite this overwhelming drawback, compelling arts that invoke an emotional reaction in the consumer have been actualized through computers, and libraries like SFML enable artists to make these experiences happen.

If you take a good look at the SFML's documentation you will see that everything operates on media in some form. Whether it be storing the media or retrieving it, sending it across a network, parsing it or sending it to a device that will make it visible to the human. Not all operations are visible to the person, and a great deal is hidden in order to provide the programmer with a simple interface through which to convey his art.

SFML enables programmers to convey physical media so that the consumers of that physical media will experience a nonphysical response, like enjoyment, anger, or even something more cerebral like understanding -- as is the case with most non-entertainment based multimedia applications.

One question I would like you to think about is whether or not SFML would be better off or worse off combining media and treating combinations as first class entities. With barely more than 3 media through which to convey information to the consumer via the computer, there are only 7 combinations: {{Sound sight time}{sound time}{sight time}{sound sight}{sound}{sight}{time}}

Currently SFML's API revolves around using composition of the last 3 to build the other 4. What are the benefits and drawbacks of this approach?

19
RenderTarget specifies that it requires a const Vertex*

VertexArray doesn't specify whether it can (or even should) be type cast to that.

Not that you would ever have to.

You could just use vertexArray.draw( ... ) rather than renderTarget.draw( ... ) since VertexArray does inhert from drawable.

But the syntax is nicer the other way. Just wondering.

20
Thankyou for the feedback nexus, I will implement your suggestions.

21
Right now I have an outstanding bug that I can't figure out how to fix.

Compile and run this code, with the class provided above:

Code: [Select]

#include "Queue.h"
#include <queue>
#include "Chrono"

using namespace std;

int main()
{
    Queue<int> q = Queue<int>();
    std::queue<int> stdq = std::queue<int>();


    for( int i = 0; i < 123; ++i )
    {
        q.push( i );
        stdq.push( i );
    }

    auto start = std::chrono::high_resolution_clock::now();
    auto end = std::chrono::high_resolution_clock::now();
    auto elapsed = std::chrono::duration_cast<std::chrono::milliseconds>(end - start);

    start = std::chrono::high_resolution_clock::now();
    for( int i = 0; i < 1234; ++i )
    {
        cout << stdq.front() << endl;
        stdq.push( stdq.front() );
        stdq.pop();
    }
    end = std::chrono::high_resolution_clock::now();
    elapsed = std::chrono::duration_cast<std::chrono::milliseconds>(end - start);
    cout << "std::queue: " << elapsed.count() << endl;

/*
    start = std::chrono::high_resolution_clock::now();
    for( int i = 0; i < 1234; ++i )
    {
        cout << q.front() << endl;
        q.push( q.front() );
        q.pop();
    }
    end = std::chrono::high_resolution_clock::now();
    elapsed = std::chrono::duration_cast<std::chrono::milliseconds>(end - start);
    cout << "Queue: " << elapsed.count() << endl;
*/
    return 0;
}


If you run it as is, it will work fine. If you uncomment the block that is commented, it will crash.

What is odd about that crash is that it doesn't happen immediately. The Queue object will cycle the same way as std::queue and spit out the correct values many many times before it fails.


EDIT:

Special thanks to Alfie275 for helping me find the bug! I modified the source in the original post to reflect the changes.

22
I'm putting it in the public domain.

I tested it so it should be bug free, but having more than one person test it is always one of the fantastic benefits of sharing code with a community.

Its just a circular buffer that uses a std::vector as a back end. When the buffer becomes full it requests that the vector allocate more space and then it copies itself into the vector. The copying is almost trivial but not quite, because circular buffers that are completely full have no empty elements, and yet extending the size of a circular buffer mandates that the new container will have empty elements. Deciding where to put these empty elements in order to preserve the qualities of a circular queue is an easy problem, but nevertheless here is my solution:

Code: [Select]
#ifndef QUEUE_H
#define QUEUE_H

#include <vector>
#include <algorithm>

/**
@brief A queue based on an underlying dynamic circular array buffer
*/
template< typename T, typename Alloc = std::allocator<T> >
class
Queue
{
    public:
        Queue( unsigned int initialCapacity = 0);

        bool
        empty();

        unsigned int
        size();

        unsigned int
        capacity();

        T
        front();

        T
        back();

        void
        push( T );

        void
        pop();

        template <class... Args>
        void
        emplace (Args&&... args);

        void
        swap( Queue& );

    protected:
    private:
        std::vector< T, Alloc >
        buffer;

        unsigned int
        frontIndex;

        unsigned int
        backIndex;

        unsigned int
        numberOfElements;
};

template< typename T, typename Alloc >
Queue< T, Alloc >::
Queue( unsigned int initialCapacity )
:   buffer( initialCapacity > 0 ? initialCapacity : 16 )
,   frontIndex(0)
,   backIndex(0)
,   numberOfElements(0)
{
}

template< typename T, typename Alloc >
void
Queue< T, Alloc >::
swap(Queue& q)
{
    buffer.swap( q.buffer );
}

template< typename T, typename Alloc >
template <class... Args>
void
Queue< T, Alloc >::
emplace( Args&& ... args )
{
    if( numberOfElements == buffer.capacity() )
    {
        std::vector< T, Alloc > v;
        v.reserve( 2*buffer.capacity() );
        std::move( buffer.begin(), buffer.begin() + frontIndex + 1, v.begin() );
        if( frontIndex != numberOfElements )
        {
            std::move_backward( buffer.begin() + backIndex, buffer.end(), v.end() );
            backIndex  += v.capacity() - buffer.capacity();
        }
        v.swap( buffer );
    }
    if( frontIndex == buffer.capacity() )
        frontIndex = 0;
    buffer.emplace( frontIndex, args ... );
    // incrementing front index of circular buffer should not require setting it to 0
    // if additional space was successfully allocated; otherwise bad_alloc exception.
    ++frontIndex;
    ++numberOfElements;
    return;
}

template< typename T, typename Alloc >
void
Queue< T, Alloc >::
pop()
{
    if( numberOfElements == 0 )
        return;
    if( backIndex == buffer.capacity() - 1 )
        backIndex = 0;
    else
        ++backIndex;
    --numberOfElements;
    return;
}

template< typename T, typename Alloc >
void
Queue< T, Alloc >::
push( T x )
{
    if( numberOfElements == buffer.capacity() )
    {
        std::vector< T, Alloc > v;
        v.reserve( 2*buffer.capacity() );
        std::move( buffer.begin(), buffer.begin() + frontIndex + 1, v.begin() );
        if( frontIndex != numberOfElements )
        {
            std::move_backward( buffer.begin() + backIndex, buffer.end(), v.end() );
            backIndex  += v.capacity() - buffer.capacity();
        }
        v.swap( buffer );
    }
    if( frontIndex == buffer.capacity() )
        frontIndex = 0;
    buffer[frontIndex] = x;
    // incrementing front index of circular buffer should not require setting it to 0
    // if additional space was successfully allocated; otherwise bad_alloc exception.
    ++frontIndex;
    ++numberOfElements;
    return;
}

template< typename T, typename Alloc >
T
Queue< T, Alloc >::
back()
{
    return buffer[frontIndex];
}

template< typename T, typename Alloc >
T
Queue< T, Alloc >::
front()
{
    return buffer[backIndex];
}

template< typename T, typename Alloc >
bool
Queue< T, Alloc >::
empty()
{
    return numberOfElements == 0;
}

template< typename T, typename Alloc >
unsigned int
Queue< T, Alloc >::
size()
{
    return numberOfElements;
}

template< typename T, typename Alloc >
unsigned int
Queue< T, Alloc >::
capacity()
{
    return buffer.capacity();
}


#endif // QUEUE_H


23
Problem resolved guys!

When creating a new compiler option and defining its settings you can't be certain that simply changing the compiler of your project in code blocks will not cause a run time error.

To be safe, define the new compiler and set it up properly and then create a new project with that compiler selected at construction. Then it should work without a hitch. Unfortunately that can mean a lot of copy and pasting, or atleast moving files around. Oh well.

24
Both of those things work -_-

I am absolutely confused.

EDIT:

Wait nvm I chose the wrong compiler at project creation. After choosing the compiler option I made for MinGW 4.9.2, it crashes on a normal hello world program and on the return 0 program.

SECOND EDIT:

well...

.

.

.

You ever make the same mistake, but the opposite, twice in a row and look like a dumbass for it? Cause yeah. It works.

26
I have SFML_STATIC defined in the compiler settings under global compiler settings along with the linker settings and search directories. And I am making sure that my selected compiler for the project is the same compiler I am defining these settings for.

I get the error once I try to run the program. It doesn't happen until I hit "run" and the console pops up, but happens before anything can be put to the console.

27
But I thought by linking static I could avoid using DLLS

These are my link libraries:

sfml-graphics-s-d
freetype
jpeg
sfml-windows-s-d
opengl32
gdi32
sfml-audio-s-d
FLAC
ogg
vorbis
vorbisenc
vorbisfile
openal32
sfml-network-s-d
ws2_32
sfml-system-s-d
winmm

I still include open OpenAL32.dll in the same folder as the executable but I keep getting that strange error.

Also, it doesn't matter if I change the programs used in the toolchain to:

C compiler is set to
gcc.exe

C++ compiler is
g++.exe

Linker is
g++.exe

Linker for static is
ar.exe

Debugger is
GDB/CDB debugger : Default

Resource compiler is
windres.exe

Make program is
mingw-32-make.exe

Since the thing compiles and links without errors, it can't be a compiler or a linker error. I must be linking to the wrong DLL like you said, but I can't figure out how or why.

28
I am getting a strange error when I try to run a hello world program with this set up.

It says

The procedure entry point _ZSt24__throw_out_of_range_fmtPKcz could not be located in the dynamic link library libstdc++6.dll

29
I tried what you provided and it links and compiles code that I know works without throwing any errors or anything.

I didn't download and build sfml, I just used to MinGW 4.9.2 package. And I didn't download the version of codeblocks that doesn't have any compilers, I just made a new compiler option. I don't see how any of that should matter if it syncs up anyway, but if it doesn't then please let me know.

I had to remember to set the toolchain up but I'm not certain I did it properly.

C compiler is set to
i686-w64-mingw32-gcc-4.9.2.exe

C++ compiler is
i686-w64-mingw32-g++.exe

Linker is
i686-w64-mingw32-g++.exe

Linker for static is
ar.exe

Debugger is
GDB/CDB debugger : Default

Resource compiler is
windres.exe

Make program is
mingw-32-make.exe

30
I tried downloading the TDM-GCC 4.9 series minGW compiler and creating a new compiler option in the build settings for the project pointing to it, and I made sure to use the correct SFML package that was compiled using that compiler.

But I still get unwind errors indicating that there is a problem with how the stack is being used, and that is typically caused by the library being compiled with a different compiler or version than the source you are linking it with.

Does that mean TDM's implementation of minGW isn't compatible?

Pages: 1 [2] 3 4 5
anything