I'm working with QT , I will to design a point (0,0) with OPENGL .
the problem is : the point Not in the middle :
http://i.stack.imgur.com/diB33.png
my code :
the header :
#ifndef BRM_H
#define BRM_H
#include <QGLWidget>
#include<qwidget.h>
class brm : public QGLWidget
{
Q_OBJECT
public:
int x , y ;
explicit brm(QWidget *parent = 0);
void initializeGL();
void paintGL();
void resize(int a ,int b);
};
#endif // BRM_H
the class :
#include<brm.h>
#include<qgl.h>
#include <GL/glut.h>
#include <GL/glu.h>
brm::brm(QWidget *parent )
: QGLWidget( parent)
{
}
void
brm::initializeGL(){
glClearColor(0,0,0,1);
}
void brm::paintGL(){
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glBegin(GL_POINTS);
glVertex2f(0.0, 0.0);
glEnd();
}
void brm::resize(int a , int b){
}
I will change the point , in the middle like this :
http://i.stack.imgur.com/WRC2e.png
why not define 2 more variables that (if you add these two with your point coordinates, you have your corrected coordinates)
so
const int MIDLLE_X = 1280 / 2; //or whatever your width divided by 2 is
const int MIDDLE_Y = 720 / 2; //or whatever your height divided by 2 is
(make them global if possible)
so (MIDDLE_X, MIDDLE_Y) as a coordinate is in the center
than you can make 2 function
int centerizeX(int x) { // wants the X coordinate
return x + MIDDLE_X;
}
int centerizeY(int y) { // wants the Y coordinate
return y + MIDDLE_X;
}
with that you can still work with your coordinates, they can even go negative. But when you want to render, draw (whatever that has to do with screen) than you should call these 2 functions to, well correct their appereance positions.
Try this:
void brm::resize(int a , int b){
glViewport(-a/2, -b/2, a, b);
}
After that, the [0, 0] position should be always at the center of the widget.
Related
Right now I have a player that i want to shoot a projectile every time the mouse is clicked. But depending on where the mouse is clicked, I want the projectile to rotate so that it appears that the projectile is always going straight out from the player. I am using sfml.
This checks if the mouse is clicked:
if (sf::Mouse::isButtonPressed(sf::Mouse::Left)){
projectile.fire();
}
which works fine, my problem is getting the rotation correct and getting the projectile to travel towards the mouse slowly and not teleporting there instantly, so basically the whole projectile.fire method.
Here is whats in my projectile.h:
#pragma once
#include "Entity.h"
class Projectile : public Entity {
public:
void fire() {
}
};
Not much because it inherits from Entity.h so here is Entity.h:
#pragma once
#include <iostream>
#include <SFML\Graphics.hpp>
#include <string>
class Entity {
public:
int x, y;
int speed = 1;
sf::Sprite sprite;
sf::Rect<float> size = sprite.getGlobalBounds();
void disappear() {
sprite.setPosition(-10, 0);
}
void setOriginToCenter() { // NEED TO FIX
sprite.setOrigin(sf::Vector2f(size.width / 2, size.height / 2));
}
void setOrigin(float x, float y) {
sprite.setOrigin(x, y);
}
sf::Vector2f getOrigin() {
return sprite.getOrigin();
}
void setPosition(float x, float y) {
sprite.setPosition(x, y);
}
sf::Vector2f getPosition() {
return sprite.getPosition();
}
void setScale(float xscale, float yscale) {
sprite.setScale(xscale, yscale);
}
void move(int ax, int ay) {
sf::Vector2f position = getPosition();
position.x += ax * speed;
position.y += ay * speed;
sprite.setPosition(position.x, position.y);
}
};
I'm not sure if I explained the problem well or provided enough code / information, so please do tell me if that is the case.
Thanks in advance for the help!
You can compute the required rotation like this:
#include <cmath>
float radians = std::atan2(buttonClickX, buttonClickY);
Most likely SFML now provides a function to rotate the sprite e.g.
sprite.rotate(radians);
You have to look up the documentation for thr exact function name.
I've finally managed to get my tiles drawn on the screen somewhat in a correct way. Although the location is a bit off and I can't seem to figure out why...
I'm using SFML for drawing.
Tile.hpp:
#ifndef TILE_HPP
#define TILE_HPP
#include <SFML/Graphics.hpp>
#include <SFML/System.hpp>
#include "textureManager.hpp"
class Tile {
public:
Tile();
Tile(sf::Vector2i coord, int biome);
~Tile();
sf::Vector2i getCoord() const { return coord; };
int getBiome() const { return biome; };
void setCoord(sf::Vector2i coord) { this->coord = coord; };
void setBiome(int biome) { this->biome = biome; };
void draw(int x, int y, sf::RenderWindow* rw);
void update(sf::Texture& texture);
private:
sf::Vector2i coord;
int biome;
sf::Sprite sprite;
};
#endif
Tile.cpp
#include <SFML/Graphics.hpp>
#include <SFML/System.hpp>
#include "textureManager.hpp"
#include "tile.hpp"
Tile::Tile()
{}
Tile::Tile(sf::Vector2i coord, int biome) {
this->biome = biome;
this->coord = coord;
}
Tile::~Tile(){}
void Tile::draw(int x, int y, sf::RenderWindow* rw)
{
sprite.setPosition(x, y);
rw->draw(sprite);
}
void Tile::update(sf::Texture& texture)
{
switch (biome)
{
// Not important here
}
}
Now the more relevant part: the drawing
void StatePlay::draw(const float dt)
{
game->window.setView(view);
game->window.clear(sf::Color::Black);
sf::Vector2f offset = camera.getLocation();
int newX = (offset.x / map.getTileSize()) - (map.chunkSize / 2);
int newY = (offset.y / map.getTileSize()) - (map.chunkSize / 2);
for (int x = 0; x < map.chunkSize; x++)
{
for (int y = 0; y < map.chunkSize; y++)
{
Tile tile = map.getTile(newX + x, newY + y);
tile.draw((newX + x) * map.getTileSize(), (newY + y) * map.getTileSize(), &game->window);
}
}
return;
}
StatePlay::StatePlay(Game* game)
{
this->game = game;
sf::Vector2f pos = sf::Vector2f(game->window.getSize()); // 1366x768
view.setSize(pos);
pos *= 0.5f; // 688x384
view.setCenter(pos);
// Initialize map
map.init(game->gameTime, game->textureManager.getImage("tileset.png"));
float w = (float) map.getWidth(); // 500
float h = (float) map.getHeight(); // 500
w *= 0.5f; // 250
h *= 0.5f; // 250
w *= map.getTileSize(); // 250 * 32 = 8000
h *= map.getTileSize(); // 250 * 32 = 8000
// Move camera
// Uses view::move from sfml to move the view with w and h
// Also sets camera private to w and h values, return with camera::getLocation()
camera.setLocation(&view, sf::Vector2f(w, h));
}
The result is that I only see the ~10 tiles squared, in the bottom left corner of my screen, covering about 3/4.
The correct tiles are chosen, but the draw location is wrong... It should draw the center of 64x64 (x 32px each) tiles, as much as fit on the screen.
I have fixed the problem. It was a very stupid mistake...
At first without drawing anything, it is normal to center the view on 0.5f * sf::View::getSize() to get the view centered in your window. So the center was already at half of my window size. When using Camera::setLocation(), I used the sf::View::move() to move the view accordingly. So when trying to center it on the map, it added the x and y correctly, but also half of my window size. This resulted in having an offset which was incorrect. Substracting or leaving those values out has fixed this stupid problem.
Thank you for the help.
The problem says:
Draw a box with rounded corners. Define a class Box, consisting of four lines and four arcs.
So I wrote the below code for that exercise:
#include <Simple_window.h>
Simple_window win(Point(100,100), 600,400, "semi-ellipse");
struct Box: Shape{
Box(Point p, int ww, int hh): w(ww), h(hh)
{ add(Point(p.x-ww,p.y-hh)); }
void d_l() const //creating 4 lines
{
Line hrz1 (Point(150,100), Point(400,100));
Line hrz2 (Point(150,300), Point(400,300));
Line ver1 (Point(507,150), Point(507,250));
Line ver2 (Point(41,150), Point(41,250));
win.attach(hrz1);
win.attach(hrz2);
win.attach(ver1);
win.attach(ver2);
}
void draw_lines() const //creating 4 arcs
{
fl_arc(point(0).x,point(0).y,w,h,30,90);
fl_arc(point(0).x,point(0).y,w,h,270,330);
fl_arc(point(0).x,point(0).y,w,h,90,150);
fl_arc(point(0).x,point(0).y,w,h,210,270);
}
private:
int w;
int h;
};
int main()
{
using namespace Graph_lib;
Box b(Point(100,100),100,50);
win.attach(b);
win.wait_for_button();
}
When I ran it I faced this exception:
Unhandled exception at 0x757FE9D7 (ole32.dll) in test.exe: 0xC0000005: Access violation reading location 0x00000004.
I know this refers to declaring Simple_window win(Point(100,100), 600,400, "semi-ellipse"); in global state. But I did that because I had to do it. The problem is that how to attach lines and also object (here b) to Simple_window win in either parts (main() function and also Box struct).
Looks like it is caused by the global creation of win. I have never run an FLTK program where anything graphical is created before main but I'm guessing that sometimes the graphics libs require some things to be in place so it is best to use them after main.
What can you do about it? If win is declared as a pointer and created inside main instead of outside main, then you won't get a crash.
...
Simple_window* win;
struct Box: Shape
{
...
win->...
...
}
int main()
{
win = new Simple_window(Point(100, 100), 600, 400, "semi-ellipse");
Box b ...
win->attach ...
win->wait ...
delete win;
}
You don't need to put anything in global space at all. You want to be passing information to the classes that need them as opposed to needing everything declared in global scope before you do anything with it.
What I write here modifies your Box class so that it also has a private member variable which is a pointer to a Simple_window class. The constructor is modified so that when you construct Box b you have to send it a pointer to the Simple_window in which it will be drawn. When you do this the pointer is assigned the pointer to the then declared Simple_Window win.
#include <Simple_window.h>
struct Box: Shape{
private:
int w;
int h;
Simple_window* window;
public:
Box(Point p, int ww, int hh,Simple_window* win_): w(ww), h(hh),window(win_)
{ add(Point(p.x-ww,p.y-hh)); }
void d_l() const //creating 4 lines
{
Line hrz1 (Point(150,100), Point(400,100));
Line hrz2 (Point(150,300), Point(400,300));
Line ver1 (Point(507,150), Point(507,250));
Line ver2 (Point(41,150), Point(41,250));
window->attach(hrz1);
window->attach(hrz2);
window->attach(ver1);
window->attach(ver2);
}
void draw_lines() const //creating 4 arcs
{
fl_arc(point(0).x,point(0).y,w,h,30,90);
fl_arc(point(0).x,point(0).y,w,h,270,330);
fl_arc(point(0).x,point(0).y,w,h,90,150);
fl_arc(point(0).x,point(0).y,w,h,210,270);
}
};
int main()
{
using namespace Graph_lib;
Simple_window* win = new Simple_window(Point(100,100), 600,400, "semi-ellipse");
Box b(Point(100,100),100,50,win);
win->attach(b);
win->wait_for_button();
}
Your lines are hard coded and independent of the constructor parameters. They could be drawn using directly the FLTK library, similarly with the arcs and placed inside the inherited from class Shape and overriden function void draw_lines() const. Then you don't need the window object to be pointer.
A possible implementation is:
Box::Box(Point p, int w, int h)
: width(w), height(h)
{
add(Point(p.x - w, p.y - h));
}
void Box::draw_lines() const
{
// draw lines with reduced length to adapt for the arcs
if (color().visibility())
{
// upper horizontal
fl_line(point(0).x + width/4, point(0).y, point(0).x + (3./4.) * width, point(0).y);
// lower horizontal
fl_line(point(0).x + width/4, point(0).y + height, point(0).x + (3./4.) * width, point(0).y + height);
// left vertical
fl_line(point(0).x, point(0).y + height/4, point(0).x, point(0).y + (3./4.)*height);
// right vertical
fl_line(point(0).x + width, point(0).y + height/4, point(0).x + width, point(0).y + (3./4.) * height);
}
// draw arcs
if(color().visibility())
{
fl_color(fill_color().as_int());
// upper left arc
fl_arc(point(0).x, point(0).y, width/2, height/2, 90, 180);
// upper right arc
fl_arc(point(0).x + width/2, point(0).y, width/2, height/2, 0, 90);
// down right arc
fl_arc(point(0).x + width/2, point(0).y + height/2, width/2, height/2, 270, 0);
// down left arc
fl_arc(point(0).x , point(0).y + height/2, width/2, height/2, 180, 270);
}
}
new here, so be gentle, I'm currently doing my Major Project for my course and, I'm not asking for homework to be done for me, i just can't wrap my head around a strange problem i am having and have not been able to find an answer for it, even on here. I'm using SDL for my Drawing.
I'm doing Object Orientated Programming with my Project or a "state Machine" (which sounds less painful in a newbies mind, believe me), and in the render part of my Class Game1.cpp i am trying to call a Draw Function of my Player Class, but for some unknown reason that i can not fathom, it just skips this function call completely.
I have no errors, i even used breakpoints to find out what was happening, but it just skipped it completely every time, it is drawing the screen black as well without fail. Any help as t why it is skipping this would be really appreciated.
I honestly feel like it's a simple rookie mistake, but any and all scrutiny is welcome of my code, anything i can do to better myself is appreciated.
Game1.cpp:
#include "Game1.h"
#include "PlayerCharacter.h"
Game1::Game1( World * worldObject )
{
//object setup
this->worldObject = worldObject;
setDone (false);
}
Game1::~Game1()
{
}
void Game1::handle_events()
{
//*******************************************
//**//////////////Call Input///////////////**
//*******************************************
//******Check for Keyboard Input*************
//******Check Keyboard Logic*****************
//******Check for Mouse Input****************
//The mouse offsets
x = 0, y = 0;
//If the mouse moved
if (SDL_PollEvent(&worldObject->event))
{
if( worldObject->event.type == SDL_MOUSEMOTION )
{
//Get the mouse offsets
x = worldObject->event.motion.x;
y = worldObject->event.motion.y;
}
}
//******Check Mouse Logic********************
}
void Game1::logic()
{
//*******************************************
//**//////////Collision Detection//////////**
//*******************************************
//******Check Player Bullet Collision Loop***
//Check for collision with enemies
//Check for collision with bitmap mask (walls)
//******Check Enemy Bullet Collision Loop****
//Check for Collision with Player
//Check for collision with bitmap mask (walls)
}
void Game1::render()
{
//*******************************************
//**////////////////Drawing////////////////**
//*******************************************
//******Blit Black Background****************
SDL_FillRect(worldObject->Screen , NULL , 0xff000000);
//******Blit Bitmap Mask*********************
//******Blit Flashlight**********************
//******Blit Map*****************************
//******Blit Pickups*************************
//******Blit Bullets*************************
//******Blit Player**************************
&PlayerCharacter.Draw; // <----- Skips this line completely, no idea why
//******Blit Enemies*************************
//******Blit Blackened Overlay***************
//******Blit HUD*****************************
//******Flip Screen**************************
SDL_Flip(worldObject->Screen);
}
Game1.h
#ifndef __Game1_H_INLUDED__
#define __Game1_H_INLUDED__
#include "GameState.h"
#include "SDL.h"
#include "ImageLoader.h"
using namespace IMGLoader;
class Game1 : public GameState
{
private:
//Menu Image
World * worldObject;
SDL_Rect PauseMenu,Item1Tile,Item2Tile,Item3Tile;
/*bool bPauseMenu, bItem1Tile, bItem2Tile, bItem3Tile;
int ButtonSpace,ButtonSize;
float x,y;
int Alpha1,Alpha2;*/
//Clipping Window
//SDL_Rect sclip,dclip;
public:
//Loads Menu resources
Game1 (World * worldObject);
//Frees Menu resources
~Game1();
//Main loop functions
void handle_events();
void logic();
void render();
};
#endif
PlayerCharacter.cpp
#include "PlayerCharacter.h"
SDL_Rect psclip,pdclip;
PlayerCharacter::PlayerCharacter ( float X, float Y, float dX, float dY, float Angle, float Speed, bool Existance, int Height, int Width, int Health, int Shield, SDL_Surface* Player ):Characters ( X, Y, dX, dY, Angle, Speed, Existance, Height, Width, Health )
{
this->Player = Player;
this->Shield = Shield;
this->Player = load_image("image\Player1.png");
}
void PlayerCharacter::setShield ( int Shield )
{
this->Shield = Shield;
}
int PlayerCharacter::getShield ( void )
{
return Shield;
}
void PlayerCharacter::Draw( )
{
psclip.x = 0; psclip.y = 0; psclip.w = 64; psclip.h = 64;
pdclip.x = 640; pdclip.y = 318; pdclip.w = 64; pdclip.h = 64;
SDL_BlitSurface(Player, &psclip, worldObject->Screen, &pdclip);
}
PlayerCharacter.h
#ifndef __PlayerCharacter_H_INCLUDED__
#define __PlayerCharacter_H_INCLUDED__
#include "Characters.h"
class PlayerCharacter : public Characters
{
private:
int Shield;
SDL_Surface* Player;
World *worldObject;
public:
PlayerCharacter ( float X, float Y, float dX, float dY, float Angle, float Speed, bool Existance, int Height, int Width, int Health, int Shield, SDL_Surface* Player );
void setShield ( int Shield );
int getShield ( void );
void Draw ( );
};
#endif
The line
&PlayerCharacter.Draw; // <----- Skips this line completely, no idea why
is not actually a function call. It's an expression that take the address of the Draw function in the PlayerCharacter class and does nothing with it.
I'm actually kind of surprised it compiles without errors, or at least tons of warnings.
You need to create a PlayerCharacter object, and then call the function in the object.
&PlayerCharacter.Draw is not a function call. PlayerCharacter::Draw() is not a static class method, so you need a PlayerCharacter object to invoke this method on.
You have a class PlayerCharacter, which defines what a PlayerCharacter is and what can be done with it. But as far as I see, you don't have a single PlayerCharacter object, i.e. no player character. If you had one, let's call him pc, then you could draw him with pc.Draw(). For that, you would have to instantiate the class, e.g. via PlayerCharacter pc( ... ), with the ... replaced by some appropriate values for the multitude of constructor parameters you have there. (You really want a default constructor, initializing all those to zero or other appropriate "start" value...)
My Code works for my purely glut implementation, but I am trying to get it to work in qt.
I have a vector of masspoints for a wire mesh system
std::vector<masspoint> m_particles;
The problem is in my qt version none of what I write really sticks and I am left with an array of zeros. Basically I am confused why the glut version has correct values but the qt one does not given that it is basically identical code. What is wrong with the qt code?
Yes I only see zeros when using qDebug. When I am calling my drawing function in the qt version all vertex points turn out to be 0 in all components so nothing is seen.
int myboog = 1;
int county = 0;
// Constructors
Cloth::Cloth(float width, float height, int particles_in_width, int particles_in_height):
m_width(particles_in_width),
m_height(particles_in_height),
m_dimensionWidth(width),
m_dimensionHeight(height),
m_distanceX(width/(float)particles_in_width),
m_distanceY(height/(float)particles_in_height)
{
//Set the particle array to the given size
//Height by width
//mparticles is the name of our vector
m_particles.resize(m_width*m_height);
qDebug() << m_particles.size();
// Create the point masses to simulate the cloth
for (int x = 0; x < m_width; ++x)
{
for (int y=0; y < m_height; ++y)
{
// Place the pointmass of the cloth, lift the edges to give the wind more effect as the cloth falls
Vector3f position = Vector3f(m_dimensionWidth * (x / (float)m_width),
((x==0)||(x==m_width-1)||(y==0)||(y==m_height-1)) ? m_distanceY/2.0f:0,
m_dimensionHeight * (y / (float)m_height));
// The gravity effect is applied to new pmasspoints
m_particles[y * m_width + x] = masspoint(position,Vector3f(0,-0.06,0));
}
}
int num = (int)m_particles.size();
for (int i=0; i<num; ++i)
{
masspoint* p = &m_particles[i];
if(myboog)
{
qDebug() << "test " << *p->getPosition().getXLocation() << county;
county++;
}
}
myboog = 0;
// Calculate the normals for the first time so the initial draw is correctly lit
calculateClothNormals();
}
Code for masspoint involved in constructor for CLoth
#ifndef MASSPOINT_H
#define MASSPOINT_H
#include <QGLWidget>
#include "vector3f.h"
class masspoint
{
private:
Vector3f m_position; // Current Location of the pointmass
Vector3f m_velocity; // Direction and speed the pointmass is traveling in
Vector3f m_acceleration; // Speed at which the pointmass is accelerating (used for gravity)
Vector3f m_forceAccumulated; // Force that has been accumulated since the last update
Vector3f m_normal; // Normal of this pointmass, used to light the cloth when drawing
float m_damping; // Amount of velocity lost per update
bool m_stationary; // Whether this pointmass is currently capible of movement
public:
masspoint& operator= (const masspoint& particle);
//Some constructors
masspoint();
masspoint(const masspoint& particle);
masspoint(Vector3f position, Vector3f acceleration);
//Like eulur integration
void integrate(float duration);
// Accessor functions
//Get the position of the point mass
inline Vector3f getPosition() const {return m_position;}
Vector stuff involved in the constructor for CLoth
#ifndef VECTOR3F_H
#define VECTOR3F_H
#include <math.h>
// Vector library to be used
class Vector3f
{
private:
float m_x, m_y, m_z;
public:
const float* getXLocation() const { return &m_x; }