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 - Gambit

Pages: [1]
1
Graphics / [solved] OpenGL calls in RenderTarget not working
« on: October 14, 2016, 08:19:28 pm »
Hey all.. again.

This is somewhat related to my last post (http://en.sfml-dev.org/forums/index.php?topic=20979.0) where I am trying to render lighting in OpenGL and have it work with SFML.

My LightEngine class has it's own RenderTexture which I'm using to contain all the state required for rendering the lights. Each frame the RenderTexture is activated, VAO is bound and for each light, uniforms are set and elements are drawn. At the end of that, the state is cleaned up and the render window (passed to the LightEngine render function) is set to draw a sprite containing the RenderTexture's Texture. Unfortunately this doesnt work. Instead, I'm presented with a black screen (since the sprite is rendered with multiply blending). If I dont use the RenderTexture it works fine.

Code:
(click to show/hide)

Desired effect: http://i.imgur.com/APbsUNE.png
Images can be downloaded here: https://www.dropbox.com/s/lvd8ztlecwvh4w2/lighting.zip?dl=1

Edit:
Well I fixed it by setting:
glViewport(0, 0, 1024, 768)
In the constructor of LightEngine just after making m_oTex active.
Result: http://i.imgur.com/f3lY8KV.gifv

2
Graphics / [solved] OpenGL with SFML (Assumed context issue)
« on: October 12, 2016, 08:55:37 am »
Hey all,

I've been struggling with some code with SFML and OpenGL for quite a few hours now and I think I have narrowed it down to an OpenGL context issue.

I'm trying to get lighting working using shaders but I'm trying to get the lights to render on top of everything else. I have made some changes to the code due to testing but I have my problem 100% reproducible.

I have added comments explaining some things  but the run down is that when I DONT draw a sprite, the "lighting" works (For debugging purposes, its a blue square that takes up the whole screen). When I DO draw a sprite, nothing is drawn to the screen at all, not even the sprite.

So without further delay, here is the code with the shaders.

main.cpp
#include <vector>

#include <SFML/Graphics.hpp>
#include <GL/glew.h>

class Light : public sf::Transformable
{
public:
   sf::Color color;
   sf::Vector3f falloff;

   void draw() const
   {
      glUniform2f(2, getPosition().x, getPosition().y);
      glUniform4f(3, color.r / 255.0f, color.g / 255.0f, color.b / 255.0f, color.a / 255.0f);
      glUniform3f(4, falloff.x, falloff.y, falloff.z);
   }
};

class LightEngine : public sf::Drawable
{
private:
   GLuint m_u32VAO, m_u32VBO, m_u32EBO;
   std::vector<Light> m_aoLights;

public:
   LightEngine()
   {
      glGenVertexArrays(1, &m_u32VAO);
      glBindVertexArray(m_u32VAO);

      glGenBuffers(1, &m_u32VBO);

      const GLfloat verts[]
      {
         -1.0f,  1.0f, 0.0f, 1.0f, // Top left
          1.0f,  1.0f, 1.0f, 0.0f, // Top right
          1.0f, -1.0f, 1.0f, 1.0f, // Bottom right
         -1.0f, -1.0f, 0.0f, 1.0f, // Bottom left
      };

      glBindBuffer(GL_ARRAY_BUFFER, m_u32VBO);
      glBufferData(GL_ARRAY_BUFFER, sizeof(verts), verts, GL_STATIC_DRAW);
      glEnableVertexAttribArray(0);
      glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(GLfloat), nullptr);
      glEnableVertexAttribArray(1);
      glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(GLfloat), reinterpret_cast<void*>(2 * sizeof(GLfloat)));

      glGenBuffers(1, &m_u32EBO);

      const GLuint elements[]
      {
         0, 1, 2,
         2, 3, 0
      };

      glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_u32EBO);
      glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(elements), elements, GL_STATIC_DRAW);

      // Create a test light
      Light oLight;
      oLight.setPosition({512, 384});
      oLight.color = sf::Color::Red;
      oLight.falloff = {0.4f, 3.0f, 20.0f};
      m_aoLights.push_back(oLight);
   }

   void draw(sf::RenderTarget& rt, sf::RenderStates states) const
   {
      glBindVertexArray(m_u32VAO);

      for (const auto& rkoLight : m_aoLights)
      {
         glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, nullptr);
      }

      glBindVertexArray(0);
   }

   ~LightEngine()
   {
      glDeleteBuffers(1, &m_u32EBO);
      glDeleteBuffers(1, &m_u32VBO);
      glDeleteVertexArrays(1, &m_u32VAO);
   }
};

int main()
{
   sf::ContextSettings oContextSettings;
   oContextSettings.antialiasingLevel = 4;
   oContextSettings.depthBits = 24;
   oContextSettings.majorVersion = 3;
   oContextSettings.minorVersion = 3;
   sf::RenderWindow oApp{{1024, 768}, "OpenGL Lighting Test", sf::Style::Default, oContextSettings};

   glewExperimental = 1;
   glewInit();

   sf::Shader oShader;
   oShader.loadFromFile("shaders/Vertex.vert", "shaders/Fragment.frag");
   sf::Shader::bind(&oShader);

   sf::RenderTexture oRT, oRTNormals;
   oRT.create(oApp.getSize().x, oApp.getSize().y);
   oRTNormals.create(oApp.getSize().x, oApp.getSize().y);
   {
      {
         sf::Texture oTex;
         oTex.loadFromFile("bg1.png");
         sf::Sprite oSpr;
         oSpr.setTexture(oTex);
         oSpr.setPosition({5.0f, 5.0f});
         oRT.draw(oSpr);
         oTex.loadFromFile("bg1_n.png");
         oRTNormals.draw(oSpr);
      }
      {
         sf::Texture oTex;
         oTex.loadFromFile("bg2.png");
         sf::Sprite oSpr;
         oSpr.setTexture(oTex);
         oSpr.setPosition({650.0f, 50.0f});
         oRT.draw(oSpr);
         oTex.loadFromFile("bg2_n.png");
         oRTNormals.draw(oSpr);
      }
      {
         sf::Texture oTex;
         oTex.loadFromFile("bg3.png");
         sf::Sprite oSpr;
         oSpr.setTexture(oTex);
         oSpr.setPosition({300.0f, 250.0f});
         oRT.draw(oSpr);
         oTex.loadFromFile("bg3_n.png");
         oRTNormals.draw(oSpr);
      }
   }
   oRT.display();
   oRTNormals.display();

   sf::Sprite oSprite{oRT.getTexture()};

   oApp.setActive(true); // Set the window to active to the LightEngine creates it's VAO, VBO and EBO on the window's context.
                         // This prevents oSprite from drawing anything. Without this call, drawing the light engine causes a crash
   LightEngine oEngine;

   bool bRunning = true;
   while (bRunning)
   {
      sf::Event oEvent;
      while (oApp.pollEvent(oEvent))
      {
         switch (oEvent.type)
         {
         case sf::Event::Closed:
         {
            bRunning = false;
            break;
         }
         }
      }

      oApp.clear();

      oApp.draw(oSprite); // Commenting this line out makes the program draw a blue square on the screen (intended)
                          // Uncommented, nothing is drawn to the screen at all, its just black.

      oApp.setActive(true);
      glActiveTexture(GL_TEXTURE0);
      glBindTexture(GL_TEXTURE_2D, oRT.getTexture().getNativeHandle());
      glActiveTexture(GL_TEXTURE1);
      glBindTexture(GL_TEXTURE_2D, oRTNormals.getTexture().getNativeHandle());
      oApp.draw(oEngine);
      glBindTexture(GL_TEXTURE_2D, 0);

      oApp.display();
   }
}
 

shaders/Vertex.vert
Code: [Select]
#version 450 core

layout(location = 0) in vec2 position;
layout(location = 1) in vec2 uv;

layout(location = 0) out vec2 out_uv;

void main()
{
    out_uv = uv;
    gl_Position = vec4(position, 0.0, 1.0);
};

shaders/Fragment.frag
Code: [Select]
#version 450 core

layout(location = 0) uniform sampler2D u_tex;      // Diffuse map
layout(location = 1) uniform sampler2D u_texNorm;  // Normal map
layout(location = 2) uniform vec2      u_lightPos;
layout(location = 3) uniform vec4      u_lightCol;
layout(location = 4) uniform vec3      u_lightFalloff;

layout(location = 0) in vec2 uv; // UV coords for this fragment

layout(location = 0) out vec4 out_color;

void main()
{
   out_color = vec4(0.0, 0.5, 1.0, 1.0);
}

Requirements:
OpenGL 4.5, SFML (Duh) and GLEW.

Desired output: Given this code, The goal is to have the blue square render on top of oSprite with multiplicative blending.

If anyone can help me figure out why drawing the sprite stops anything from rendering that would be helpful.

Images can be found as a zip here: https://www.dropbox.com/s/lvd8ztlecwvh4w2/lighting.zip?dl=1

It could also be worth noting that glGetError returns 0 in every frame and I grabbed the latest GIT since it has context related changes and it didnt fix the problem I am having.

3
Graphics / SFML with Qt - Cannot create OpenGL context
« on: January 21, 2015, 05:05:26 pm »
I'm trying to get SFML 2.2 working with Qt 5.4 (Free) but it is giving me some problems. I've tried researching the problem I'm currently having but it seems I'm the only one having it so I guess I'm doing something wrong.

The error is: Failed to set pixel format for device context -- cannot create OpenGL context. I understand that this is an SFML error, however, all of my other SFML projects work perfectly fine, so I'm assuming this is to do with how I'm using Qt.

My current project consists of 3 files, main.cpp, QTSFMLWindow.cpp/hpp. I have attached the source code and a test image, but I'll paste the code here as well.

main.cpp
#include <QtWidgets/qapplication.h>
#include <QtWidgets/qframe.h>

#include "QTSFMLWindow.hpp"

#include <memory>

int main(int argc, char** argv)
{
   QApplication oQApp(argc, argv);

   QFrame oWindowFrame;
   oWindowFrame.setWindowTitle("QT SFML Test");
   oWindowFrame.resize(800, 600);
   oWindowFrame.show();

   QTSFMLWindow oWindow{oWindowFrame, {5, 5}, {oWindowFrame.size().width() / 2u, oWindowFrame.height() - 10u}};
   oWindow.show();
   system("pause"); // uncomment this line for the proper error

   return oQApp.exec();
}
 

QTSFMLWindow.hpp
#ifndef QTSFMLWINDOW_HPP
#define QTSFMLWINDOW_HPP

#include <SFML/Graphics.hpp>
#include <QtWidgets/qwidget.h>
#include <QtCore/qtimer.h>

#include <cstdint>
#include <memory>

class QTSFMLWindow : public QWidget, public sf::RenderWindow
{
private:
   bool m_bInitialized;
   QTimer m_oQTimer;
   sf::Texture m_oTexture;
   sf::Sprite m_oSprite;

public:
   QTSFMLWindow(QWidget& roParent, const sf::Vector2f v2fOffset, const sf::Vector2u v2uSize);
   ~QTSFMLWindow();

   void showEvent(QShowEvent* poEvent);
   void paintEvent(QPaintEvent* poPaintEvent);
};

#endif // QTSFMLWINDOW_HPP
 



QTSFMLWindow.cpp
#include "QTSFMLWindow.hpp"

#include <iostream>

QTSFMLWindow::QTSFMLWindow(QWidget& roParent, const sf::Vector2f v2fOffset, const sf::Vector2u v2uSize)
   : QWidget{&roParent}
   , m_bInitialized{false}
{
   setAttribute(Qt::WA_PaintOnScreen);
   setAttribute(Qt::WA_OpaquePaintEvent);
   setAttribute(Qt::WA_NoSystemBackground);
   setFocusPolicy(Qt::StrongFocus);

   resize({static_cast<int>(v2uSize.x), static_cast<int>(v2uSize.y)});
   move({static_cast<int>(v2fOffset.x), static_cast<int>(v2fOffset.y)});

   m_oQTimer.setInterval(0);

   if (!m_oTexture.loadFromFile("vent.png")) {
      std::cout << "vent loading failed" << std::endl;
      return;
   }

   m_oSprite.setTexture(m_oTexture);
   m_oSprite.setPosition({5, 5});
}

QTSFMLWindow::~QTSFMLWindow()
{
   //
}

void QTSFMLWindow::showEvent(QShowEvent* poEvent)
{
   if (m_bInitialized)
      return;

   sf::RenderWindow::create({WId()});

   connect(&m_oQTimer, SIGNAL(timeout()), this, SLOT(repaint()));
   m_oQTimer.start();

   m_bInitialized = true;
}

void QTSFMLWindow::paintEvent(QPaintEvent* poPaintEvent)
{
   clear(sf::Color::White);
   draw(m_oSprite);
   display();
}
 

The clear, draw and display functions are all called when they should be (Each frame, stepped through with a debugger), however nothing gets rendered.

The error: Failed to activate the window's context is also spammed twice in the console per frame and also when the application changes focus, but I'm assuming it is related to the original error.

I understand this should probably be in General Help or something but considering that the error message is in the graphics part of the code, I thought I would post it here. Any help resolving this issue would be appreciated.

4
Network / Sending enumerations in sf::Packet with C++11
« on: December 23, 2014, 12:18:05 am »
A while back I was having some issues regarding sending enums through sf::Packet. The primary solution was to cast the enum to an int, send it, then do more casting on the receiving end. The resulting code looked something like this:

enum class MyEnum
{
   VALUE1,
   VALUE2
}

...

// Sending
sf::Packet oPacket;
oPacket << static_cast<std::uint8_t>(MyEnum::VALUE1);

...

// Receiving
std::uint8 ui8Value;

sf::Packet oReceived;
// receive the packet
oReceived >> ui8Value;
MyEnum eMyEnume = static_cast<MyEnum>(ui8Value);
 

This is quite messy and verbose and its horrible to maintain, especially if MyEnum grew to include values which exceeded values of 255.

The simple option would be to cast everything to either int32 or in64 (And their unsigned counter-parts), but thats boring (And casting is ugly).

So I wrote some sf::Packet<</>> overloads to allow sending enums through sf::Packet with the help of templates and C++11 underlying types for enumerations and type traits:

template<typename T>
inline typename std::enable_if<std::is_enum<T>::value, sf::Packet&>::type
operator<<(sf::Packet& roPacket, const T& rkeMsgType)
{
   return roPacket << static_cast<std::underlying_type<T>::type>(rkeMsgType);
}

template<typename T>
inline typename std::enable_if<std::is_enum<T>::value, sf::Packet&>::type
operator>>(sf::Packet& roPacket, T& reMsgType)
{
   std::underlying_type<T>::type xMsgType;
   roPacket >> xMsgType;
   reMsgType = static_cast<T>(xMsgType);

   return roPacket;
}
 

The code is probably a bit overkill, but it handles the correct casting for implicit enum types (signed int) explicit types.

The resulting send/receive code would look like this:
// Sending
sf::Packet oPacket;
oPacket << MyEnum::VALUE1;

...

// Receiving
MyEnum eMyEnume;

sf::Packet oReceived;
// receive the packet
oReceived >> eMyEnume;
 

The code has been tested and works as far as I have tested it.

5
Graphics / Fallback fonts for multiple languages and characters.
« on: November 10, 2014, 04:39:25 am »
Hi all.

I was wondering if it was at all possible to implement a feature into sf::Font to check if the font has a certain character. A usage example would be to use the arial font with asian characters with correct use of wide strings. The result is that the characters are displayed as boxes. While I dont have a problem with this, I do have a problem that I cant tell if a font has these characters or not, so being able to check would be helpful since I could swap to another font to display these foreign characters.

This isnt COMPLETELY relevant, but I noticed that Steam does this seamlessly but that might be a feature in SDL I'm not sure.

6
Window / Joystick API design suggestion
« on: October 26, 2014, 06:17:31 am »
Hi all, I have been reading over the API for the joystick in SFML and it seems a little counter-intuitive. All methods in the sf::Joystick class are static and I dont understand why. If I may offer a suggestion, sf::Joystick should be an object constructed with an int (Being the device index), and all other methods act on that. For example:

sf::Joystick oJoystick(0);
oJoystick.hasAxis(sf::Joystick::X);
 

I understand that such a change in the API would cause a lot of problems with backwards compatibility but it better suits OOP and it looks better. Some people might be thinking that if this change were to go through, sf::Mouse and sf::Keyboard should also be objects except that as far as I know, SFML does not support multiple keyboards and mice, but the joystick API supports multiple joysticks so sf::Joystick being an object makes a bit more sense and in the long-run the code looks better and so does the API in my opinion.

Pages: [1]