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 - Jamin Grey

Pages: [1]
1
Feature requests / sf::BlendMode::apply() function
« on: December 17, 2014, 05:15:55 am »
Hi! I love the new sf::BlendMode. I was planning to work around it with my own butchered hacks when SFML added it (I was specifically wanting Multiply2, or as PaintShopPro calls it, 'Overlay'). Thank you, gents!

Anyway, many of SFML's classes can be used directly with OpenGL, instead of going through SFML's 2D graphics API.

For example, sf::Shader and sf::Texture both have a bind() function.

Currently, if I want to use sf::BlendMode with OpenGL directly, I basically have to replicate the code in void sf::RenderTarget::applyBlendMode(const BlendMode& mode); (RenderTarget.cpp, line 421 in the current master)

Why not extract that exact same code into a new sf::BlendMode function (possibly called 'apply()' or maybe 'bind()')?

It'd look like this:
void BlendMode::apply() const
{
    // Apply the blend mode, falling back to the non-separate versions if necessary
    if (GLEXT_blend_func_separate)
    {
        glCheck(GLEXT_glBlendFuncSeparate(
            factorToGlConstant(colorSrcFactor), factorToGlConstant(colorDstFactor),
            factorToGlConstant(alphaSrcFactor), factorToGlConstant(alphaDstFactor)));
    }
    else
    {
        glCheck(glBlendFunc(
            factorToGlConstant(colorSrcFactor),
            factorToGlConstant(colorDstFactor)));
    }

    if (GLEXT_blend_equation_separate)
    {
        glCheck(GLEXT_glBlendEquationSeparate(
            equationToGlConstant(colorEquation),
            equationToGlConstant(alphaEquation)));
    }
    else
    {
        glCheck(GLEXT_glBlendEquation(equationToGlConstant(colorEquation)));
    }
}
(The only change is instead of taking 'mode' as a parameter, the class is directly using its own members)

And then RenderTarget::applyBlendMode() would be changed to this:
void RenderTarget::applyBlendMode(const BlendMode& mode)
{
     mode.apply();
     m_cache.lastBlendMode = mode;
}

Perfectly backwards compatible with prior SFML versions, cleans up RenderTarget of some of its responsibilities, and also makes sf::BlendMode more flexible and usable for general OpenGL users.

(Sorry for not contributing it directly to the GitHub. I don't currently have a GitHub account, and don't use git for my source control)

2
Hi, I'm new to OpenGL and shaders. Also, my math is poor so matrixes are throwing me for a loop.  :(
I'm trying to understand them while working through this task, and bits and pieces are coming together, but it's too many things coming at once so I'm getting confused.

I'm trying to take one grayscale sf::Texture, and use it as the alpha channel for another sf::Texture.
Okay, easy enough:
gl_FragColor = (texture2D(texture, gl_TexCoord[0].xy) * gl_Color);
gl_FragColor.a = texture2D(mask, gl_TextCoord[0].xy).a;
(where 'mask' is uniform sampler2D mask; passed into the shader)

My difficulties arise because:
A) I want the textures to be able to be mirrored horizontally and/or vertically.
B) I want the textures to be able to be rotated (the mask rotated relative to the main texture, and the mask only rotated in 90 degree increments)
C) I want the mask to stretch itself to conform to the size of the texture if the mask happens to be larger or smaller or of unequal width/height.
D) I want the two textures to be rotated seperately from each other.

For the sake of convenience and experimentation, I'm doing this in a C++ function called 'SfmlDrawTextureWithMask()', where I pass in the textures separately with their rotations and other settings.

Right now, I'm playing with a shader like this: (SFML's basic vertex shader example)
uniform mat4 textureOrientation;
//uniform mat4 maskOrientation;

void main()
{
    // transform the vertex position
    gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;

    // transform the texture coordinates
    gl_TexCoord[0] = gl_TextureMatrix[0] * textureOrientation * gl_MultiTexCoord0;

    // forward the vertex color
    gl_FrontColor = gl_Color;
}

My problems so far, are that:
A) 'textureOrientation' isn't stretching to fill the texture, it's sampling outside of the texture and just has the usual bands of the border pixels:


I realize that this is because I'm rotating the texture coordinates and not the vertices themselves, and that I can use sf::Transform to rotate the primary sf::Texture by passing it into the secondary parameter of sf::RenderTarget::draw() - still, since I'm wanting to rotate the mask texture separately, I'm not sure exactly how to compensate for the rotation - I guess I could pass in the mask texture's size, use it to normalize the mask's texture coordinates, and then re-adjust with width and height swapped?

B) I don't know how gl_TexCoord[0] is created or passed to the fragment shader. It looks like an array (because of my C++ background), but I don't know the size of the array, so I don't know if that means I can just start using gl_TexCoord[1] to hold my mask texture's texture coordinates or if that'll overflow the buffer.

Why does gl_TexCoord[] and gl_MultiTexCoord0 exist? That seems to me like OpenGL supports binding multiple textures at once, but SFML only publicly exposes binding one texture at a time. Am I way off track here?
Is gl_TexCoord[1] available for me to use, and if so, do I have to do anything special to 'enable' it? I mean, I can't just use gl_TexCoord[999] can I?

Or to clarify my question: How do I pass my mask's separate texture coordinates from the vertex shader to the fragment shader (keeping in mind that they need to be interpolated for each fragment)?

And how do I get my mask's separate texture coordinates into the vertex shader in the first place? Especially considering that the mask might be only a subrect of a large texture container multiple masks. The first texture's tex coords are stored in gl_MultiTexCoord0, right? And they are passed into SFML using the attributes of the vertices - but a secondary mask texture wouldn't have vertices. How can I use SFML (or failing that, OpenGL) to put my mask texture's texcoords into gl_MultiTexCoord1?

Please keep your answers simple! I'm new to GLSL and OpenGL.  :-\

3
Graphics / Why does SFML unbind the shader after each draw call?
« on: December 25, 2013, 10:22:21 pm »
In the source of SFML 2.0, in void RenderTarget::draw(...), I see this code:

Code: [Select]
void RenderTarget::draw(const Vertex* vertices, unsigned int vertexCount,
                        PrimitiveType type, const RenderStates& states)
{
    // Nothing to draw?
    if (!vertices || (vertexCount == 0))
        return;

    if (activate(true))
    {
        // First set the persistent OpenGL states if it's the very first call
        if (!m_cache.glStatesSet)
            resetGLStates();

        // Check if the vertex count is low enough so that we can pre-transform them
        bool useVertexCache = (vertexCount <= StatesCache::VertexCacheSize);
        if (useVertexCache)
        {
            // Pre-transform the vertices and store them into the vertex cache
            for (unsigned int i = 0; i < vertexCount; ++i)
            {
                Vertex& vertex = m_cache.vertexCache[i];
                vertex.position = states.transform * vertices[i].position;
                vertex.color = vertices[i].color;
                vertex.texCoords = vertices[i].texCoords;
            }

            // Since vertices are transformed, we must use an identity transform to render them
            if (!m_cache.useVertexCache)
                applyTransform(Transform::Identity);
        }
        else
        {
            applyTransform(states.transform);
        }

        // Apply the view
        if (m_cache.viewChanged)
            applyCurrentView();

        // Apply the blend mode
        if (states.blendMode != m_cache.lastBlendMode)
            applyBlendMode(states.blendMode);

        // Apply the texture
        Uint64 textureId = states.texture ? states.texture->m_cacheId : 0;
        if (textureId != m_cache.lastTextureId)
            applyTexture(states.texture);

        // Apply the shader
        if (states.shader)
            applyShader(states.shader);

        // If we pre-transform the vertices, we must use our internal vertex cache
        if (useVertexCache)
        {
            // ... and if we already used it previously, we don't need to set the pointers again
            if (!m_cache.useVertexCache)
                vertices = m_cache.vertexCache;
            else
                vertices = NULL;
        }

        // Setup the pointers to the vertices' components
        if (vertices)
        {
            const char* data = reinterpret_cast<const char*>(vertices);
            glCheck(glVertexPointer(2, GL_FLOAT, sizeof(Vertex), data + 0));
            glCheck(glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(Vertex), data + 8));
            glCheck(glTexCoordPointer(2, GL_FLOAT, sizeof(Vertex), data + 12));
        }

        // Find the OpenGL primitive type
        static const GLenum modes[] = {GL_POINTS, GL_LINES, GL_LINE_STRIP, GL_TRIANGLES,
                                       GL_TRIANGLE_STRIP, GL_TRIANGLE_FAN, GL_QUADS};
        GLenum mode = modes[type];

        // Draw the primitives
        glCheck(glDrawArrays(mode, 0, vertexCount));

        // Unbind the shader, if any
        if (states.shader)
            applyShader(NULL);

        // Update the cache
        m_cache.useVertexCache = useVertexCache;
    }
}

That makes me curious. If it's bad for performance to change shaders and textures, so developers try to reduce those calls as much as possible, why does SFML unbind the shader after every draw call?

Is this a precaution incase the user of SFML lets the sf::Shader go out of scope?
Does the unbinding and then rebinding of the same shader cause a small hit to the performance?

I also noticed the sf::Texture getting bound, but not later unbound. Why is the sf::Shader unbound after the call, but not the sf::Texture?

I use SFML alot, and I'm an OpenGL noob trying to learn it, and I just encountered this in SFML's source and was curious.
If my code is entirely positive that the sf::Shader won't get destructed between two draw calls, do I still have to unbind it between them?
Also, do shaders ever need to be unbound when the program ends, or can I leave the last used shader bound? e.g. is it like calling delete() on what you new(), and important unbinding-processes are occuring, or is 'unbinding' just saying, "use the default shader" and not actually required to clean up when the program is exiting?

4
I wrote a function that allows you to draw a sf::Texture without using a sf::Sprite, and also allows you to flip/mirror the texture. I needed this for my own project, but hopefully others find it useful as well.

Here's the code:
void SfmlDrawTexture(sf::RenderTarget &destination, const sf::Vector2f &location, const sf::Texture &texture,
                                         sf::IntRect subRect, const sf::Color &coloration, float rotation,
                                         bool flipHorizontally, bool flipVertically, sf::BlendMode blendMode, const sf::Shader *shader)
{
        //If no rect is specified, use the entire texture.
        if(subRect.width == 0 || subRect.height == 0)
        {
                subRect.top = 0;
                subRect.left = 0;
                subRect.width = texture.getSize().x;
                subRect.height = texture.getSize().y;
        }
       
        //Set the position in space.
        sf::Transform translation;
        translation.translate(location);
       
        //Set the rotation (rotated around the center, since this sf::Transform wasn't moved).
        sf::Transform rotationTransform;
        rotationTransform.rotate(rotation);

        //Setup the render state.
        sf::RenderStates states(blendMode, (translation * rotationTransform), &texture, shader);
       
        //Setup the vertices and their attributes.
        sf::Vertex vertices[4];
       
        //The transparency:
        vertices[0].color = coloration;
        vertices[1].color = coloration;
        vertices[2].color = coloration;
        vertices[3].color = coloration;
       
        //The pre-transform position and size:
        float widthBeforeTransform = static_cast<float>(subRect.width);
        float heightBeforeTransform = static_cast<float>(subRect.height);
    vertices[0].position = sf::Vector2f(0, 0);
    vertices[1].position = sf::Vector2f(0, heightBeforeTransform);
    vertices[2].position = sf::Vector2f(widthBeforeTransform, heightBeforeTransform);
    vertices[3].position = sf::Vector2f(widthBeforeTransform, 0);
       
        //Calculate the texture coordinates:
        float left   = static_cast<float>(subRect.left);
    float right  = left + subRect.width;
    float top    = static_cast<float>(subRect.top);
    float bottom = top + subRect.height;
       
        //If we're mirroring, swap the texture coordinates vertically and/or horizontally.
        if(flipVertically)              std::swap(left, right);
        if(flipHorizontally)    std::swap(top, bottom);

        //Set the texture coordinates:
    vertices[0].texCoords = sf::Vector2f(left, top);
    vertices[1].texCoords = sf::Vector2f(left, bottom);
    vertices[2].texCoords = sf::Vector2f(right, bottom);
    vertices[3].texCoords = sf::Vector2f(right, top);
       
        //Use the sf::RenderTarget to draw the vertices using the sf::RenderStates we set up.
        destination.draw(vertices, 4, sf::Quads, states);
}
 

To handle mirroring, I swapped the texture coordinates... currently this only works because SFML doesn't disable back-face culling (at least, not in SFML 2.0), but whatever. =)

It'd be nice if this (flipping/mirroring) was available as a feature for sf::Sprites.

5
I want to load a sf::Texture from memory, return it immediately, but start a new thread (using C++11's std::thread) that will (in a local thread-owned sf::Image) modify the pixel that, and upload the new pixel data when finished.

Can I call sf::Texture::update(sf::Image) from this new thread? My code doesn't call that specific function anyplace else, though it's possible the texture could be getting drawn at the exact same time.

6
Graphics / Keeping objects at the same size, regardless of zoom
« on: July 26, 2012, 10:38:47 pm »
What's the best way to keep an object, positioned and moved around in the view, drawn at the same size regardless of that view's size?

What I mean is, I want some sf::Text to be drawn at an easy-to-read size, even when the view is zoomed way out. But I don't want to just reset the view like I do for drawing a GUI, because the text is positioned by the view it's inside of.

The only way I can think of doing this, is by not messing with the view at all and knowing how much the view is zoomed in (say, 500%), zoom in the text by the same amount. Is that the best option?

Note: To 'zoom in' the view, I do this:
worldView.setSize((originalWidth * worldZoom), (originalHeight * worldZoom));

(I'm using SFML 2)

7
General / Joystick Axes - Question
« on: February 16, 2012, 03:28:33 am »
I'm using SFML 1.6, on Win7 32bit.

SFML 1.6 has constants for these Joystick axes:
X,Y,Z,R,U,V, and POV.

SFML 2 has the same axes, but replaces POV with PovX and PovY.

My questions are:
(Barring any really uncommon gamepads that do everything differently and illogically just to be contrary - only focusing on very common gamepads that my users are likely to have)

1) Is 'X' always horizontal on a joystick, 'Y' always vertical, 'Z' always horizontal, 'R' always vertical, and so on? Or do I have no (in-general) guarantee of their real-world orientation on the controller?

2) Is 'POV' a different way that some gamepads internally handle joysticks, or is it an entirely different (from the gamepad user's perspective) type of control? Basically, is POV still a joystick on a gamepad, or is it a different type of control on a gamepad?

3) What's the reasoning of putting the joystick position range between -100.0f and 100.0f? Why not -1.0 to 1.0? Is that how Windows handles it, or how gamepads normally give the values, or does SFML translate it to that? Why's it like that? Just curious. =)

4) Is there any way to know that axis 'A' is paired with axis 'B'? For example, can I be reasonably certain that if AxisX and AxisY exist, they are on the same joystick (even if I don't know for which is horizontal and which is vertical)?

5) How can I detect if two axes are on the same gamepad joystick or if they belong to separate joysticks on the same gamepad? Can I get enumerate the joysticks on the gamepad, and detect if an axis belongs to it?

8
Graphics / Offscreen rendering?
« on: February 26, 2011, 07:03:42 am »
Can I do offscreen rendering in SFML 1.6? If so, how?

I notice there is a sf::RenderTarget that sf::RenderWindow uses - does it work, if I inherit it and make my own render target? Is there third party SFML additions that supply offscreen rendering?

I'm aware of sf::RenderImage in SFML 2, but I'm using 1.6 for now, until I'm 100% certain about Mac OSX stability by an official SFML 2 release for it.

Thanks in advance!

9
Graphics / sf::RenderWindow::SetView() is giving two different values.
« on: January 25, 2011, 02:31:00 am »
I'm trying to alter the view of a sf::RenderWindow - unfortunately, it seems to behavior weirdly, if I try to alter it from within a function.

I'm using version 1.6 (the official current version of SFML).

Code: [Select]
#include <SFML/Graphics.hpp>
#include <iostream>

void ChangeView(sf::RenderWindow *window)
{
    window->SetView(sf::View(sf::FloatRect(0, 0, 640, 480)));
}

int main(int argc, char *argv[])
{
    sf::RenderWindow window(sf::VideoMode(800, 600), "Titlebar text");
   
    //Get default view's coordinate.
    sf::Vector2f pos1 = window.ConvertCoords(0, 0);

    //Change the view.
    window.SetView(sf::View(sf::FloatRect(0, 0, 640, 480)));
   
    //Get the coordinate now.
    sf::Vector2f pos2 = window.ConvertCoords(0, 0);

    //Change the view via a function.
    ChangeView(&window);
   
    //Get the view now.
    sf::Vector2f pos3 = window.ConvertCoords(0, 0);

    //Print out the results. Why is the third one different?
    std::cout << "Pos1: (" << pos1.x << ", " << pos1.y << ")\n"
              << "Pos2: (" << pos2.x << ", " << pos2.y << ")\n"
              << "Pos3: (" << pos3.x << ", " << pos3.y << ")\n";

    return 0;
}


See how the function 'ChangeView' is calling completely identical code to when I call 'SetView' in main() itself? Both are calling it like this:
Code: [Select]
window.SetView(sf::View(sf::FloatRect(0, 0, 640, 480)));

However, both are giving different results!

My output:
Pos1: (0, 0)
Pos2: (0, 0)
Pos3: (0, 240)
<--- Why's this one different?

I've been looking at this for a few hours now, and can't find my mistake. Why are the results different if I'm calling them in the exact same way? Anyone know what I'm doing wrong?

10
Audio / Saving to .ogg?
« on: May 14, 2009, 02:39:34 am »
I'm trying to save recorded sound to a .ogg format. Using a sf::SoundBuffer, I call the SaveToFile function, and named the file 'test.ogg', but the file doesn't appear. 'test.wav' works, though.

I see on the features page, "Can load and save standard sound formats : ogg, wav, flac, aiff, au, raw, paf, svx, nist, voc, ircam, w64, mat4, mat5 pvf, htk, sds, avr, sd2, caf, wve, mpc2k, rf64". Is saving to ogg vorbis supported in SFML, or just the loading?

I couldn't see .ogg at all (saving or loading), on libsndfile's homepage, so I'm probably looking in the wrong place.

Pages: [1]