Jump to content

Skrakle

Members
  • Posts

    79
  • Joined

  • Last visited

Posts posted by Skrakle

  1. I'm setting my camera based on my model's position/rotation but i'd like the camera to be positioned a little further back so i can actually see the model move, i think what i'm looking for is something like vector forward.

     

    Right now, i'm setting it at the exact same x/z coordinates.

     Vec3 pos = player_entity->model->GetPosition();
     camera->SetPosition(Vec3(pos.x, pos.y + 2, pos.z));
    

     

    What would be required to re-calculate the new x/z coordinates of the camera?

  2. You can implement something like this yourself with C++ and Texture::SetPixels().

    I haven't thought of doing it that way, i'll give that a try. I've also been trying to search for the .tex file format specification, i need to know its size but i'm not getting any good results from search engines, do you have any documentation about it?

    post-14340-0-17619200-1430418824.png

  3. I have lots of gui graphics and i would like to combine them into a single file that won't be packaged in the zip file, would it be possible to instruct the texture loader to load from file offset and length?

     

    Something like:

    Texture* Load(const std::string& path, int flags=0, const uint64 fileid=0, uint64 file_offset, uint64 file_length)

  4. I'm using a buffer to draw a minimap along with a dot representing my position. The dot is a normal texture that i'm loading, 1x1 white image and when i draw it on the buffer, i want to set its color like in context->SetColor but it stays white. Is there some way to obtain the context of a buffer?

     

          	 Buffer* buf = Buffer::Create(minimap_width, minimap_height);
               buf->Enable();
               buf->Clear();
    
          	 buf->SetColor(1, 1, 0, 1);  // does not set color like context->SetColor does
    
          	 //minimap->Draw(0, 0);
          	 //buf->SetColorTexture(minimap);
          	 dot->Draw(pos.x, pos.y, 5, 5);    // resizing my dot 5x5
          	 buf->SetColorTexture(dot);
    
               buf->Disable();
    
               m_rendertarget = buf->GetColorTexture();  // dump the buffer into a texture
               buf->Release();
    

  5. I solved the alpha issue using this:

     

    	 	 m_texture_elements[0]->texture->Draw(0, 0, m_texture_elements[0]->texture->width, m_texture_elements[0]->texture->height);
    
    
    		glEnable(GL_BLEND);
    		glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
    		m_texture_elements[0]->texture->Draw(50, 0, m_texture_elements[0]->texture->width, m_texture_elements[0]->texture->height);
    
    		glEnable(GL_BLEND);
    		glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
    		m_texture_elements[0]->texture->Draw(80, 0, m_texture_elements[0]->texture->width, m_texture_elements[0]->texture->height);
    

     

    Every time i draw sequentially on the same buffer, i have to enable GL_BLEND and set blend flags, is it normal?

    post-14340-0-66909500-1429552843.png

  6. The loaded texture is probably a different format.

    It's an uncompressed RGBA texture 128x32, MipMaps:8.

     

    I'm trying to create a render target (buffer) and draw on it. Then i later found i could just texture->draw on a created buffer. The only problem i'm facing now is that if i try to draw another image with alpha over the first one, it draws it opaque. I did try glEnable(GL_BLEND) but it didn't work.

     

     

     m_buffer->Enable();
    m_buffer->SetColor(m_background_color);
    m_buffer->Clear();
    m_buffer->SetColor(1, 1, 1, 1);
    
    // first one draws fine
     m_texture_elements[0]->texture->Draw(0, 0, m_texture_elements[0]->texture->width, m_texture_elements[0]->texture->height);
    
    // not applying alpha over first one
     m_texture_elements[0]->texture->Draw(60, 0, m_texture_elements[0]->texture->width, m_texture_elements[0]->texture->height);
    

    post-14340-0-33280900-1429548739.png

  7. I took this example from the documentation for SetPixel, i commented out Texture::Create and replaced it with Texture::Load but it crashes when doing memcpys but it doesn't if i don't load a texture and use Create instead. The texture loads fine, i'm able to display it.

     

    Error:

    HEAP[Test.debug.exe]: Heap block at 0655D900 modified at 0656192C past requested size of 4024

    Test.debug.exe has triggered a breakpoint.

     

     

     

    In App::Start

    
    //texture = Texture::Create(256, 256);
    
    texture = Texture::Load("mytexture.tex"); // texture is defined in App.h
    
    //Create a buffer to store pixel data in
    int datasize = texture->GetMipmapSize(0);
    char* pixels = (char*)malloc(datasize);
    
    //Get the pixel data from the texture and invert it
    texture->GetPixels(pixels);
    char r, g, b, a;
    for (int x = 0; x<texture->GetWidth(); x++)
    {
     for (int y = 0; y<texture->GetHeight(); y++)
     {
    	 int p = (x*texture->GetWidth() + y) * 4;
    	 memcpy(&r, pixels + p + 0, 1);
    	 memcpy(&g, pixels + p + 1, 1);
    	 memcpy(&b, pixels + p + 2, 1);
    
    	 r = 255 - r;
    	 g = 255 - g;
    	 b = 255 - b;
    
    	 memcpy(pixels + p + 0, &r, 1);
    	 memcpy(pixels + p + 1, &g, 1);
    	 memcpy(pixels + p + 2, &b, 1);
     }
    }
    
    //Set the modified pixel data
    texture->SetPixels(pixels);
    free(pixels);
    

    [c++] SetPixel/memcpy crash

  8. Here's a new lib that i just finished that will allow game controller support for Lua fans! smile.png

     

    EDIT:

    Source: https://onedrive.live.com/redir?resid=1653f4923c37f970!278&authkey=!ABW8a3PdvzR_8cE&ithint=file%2czip

     

    Binaries (dll & so): https://onedrive.live.com/redir?resid=1653f4923c37f970!284&authkey=!AM0p2lTBH1mMSzk&ithint=file%2czip

     

    A lua example is provided, you can simply overwrite your existing App.lua with mine on a new test project.

     

    * Note: Lua sandbox must be disabled to use libs.

     

    Unfortunately i don't have linux installed so i couldn't compile it for that platform and I was able to compile it under Linux but i didn't get the chance to test it as i don't have the sdl2 binary libs.

     

    I included the full source should anyone want to re-compile it. Those that don't want to, simply copy LuaGamePad.dll file where your game executable is. You'll need to copy SDL2.DLL there as well, it's included.

     

     

    Tested with:

    - Logitech Rumblepad

    - Xbox 360 controller (XInput)

     

     

    Cheers!

    • Upvote 4
  9. Here's the game controller class i just finished. Copy the SDL folder in your source directory (currently SDL2-2.0.3). Include SDL2.lib in your project and copy SDL2.DLL in the same folder as your executable.

     

    Edit:

    Added 2 parameters in the init method to enable/disable auto reacquire.

     

     

    App.h

    #pragma once
    #include "Leadwerks.h"
    #include "Game_Controller.h"
    
    
    using namespace Leadwerks;
    
    class App
    {
    public:
    Leadwerks::Window* window;
    Context* context;
    World* world;
    Camera* camera;
    
    Game_Controller* joysticks[8];
    
    App();
    virtual ~App();
    
    virtual bool Start();
    virtual bool Loop();
    };
    

     

     

     

    App.cpp

    #include "App.h"
    
    using namespace Leadwerks;
    App::App() : window(NULL), context(NULL), world(NULL), camera(NULL) {}
    App::~App() { delete world; delete window; }
    
    bool App::Start()
    {
    window = Leadwerks::Window::Create("Joystick");
    context = Context::Create(window);
    world = World::Create();
    camera = Camera::Create();
    window->HideMouse();
    
    if (SDL_InitSubSystem(SDL_INIT_JOYSTICK) < 0)
    {
    System::Print("Unable to init joystick system");
    }
    else
    {
    joysticks[0] = new Game_Controller();
    if (joysticks[0]->Init(0, 15000, true, true))
    {
    System::Print("** Using joystick : " + joysticks[0]->GetName());
    }
    }
    
    window->ShowMouse();
    
    return true;
    }
    
    bool App::Loop()
    {
    //Close the window to end the program
    if (window->KeyDown(Key::Escape))
    return false;
    
    
    if (joysticks[0])
    {
    joysticks[0]->ProcessEvents();
    
    if (joysticks[0]->AXIS_UP) System::Print("AXIS UP ; " + std::to_string(joysticks[0]->axis_y));
    if (joysticks[0]->AXIS_DOWN) System::Print("AXIS DOWN ; " + std::to_string(joysticks[0]->axis_y));
    if (joysticks[0]->AXIS_LEFT) System::Print("AXIS LEFT ; " + std::to_string(joysticks[0]->axis_x));
    if (joysticks[0]->AXIS_RIGHT) System::Print("AXIS RIGHT ; " + std::to_string(joysticks[0]->axis_x));
    if (joysticks[0]->DPAD_UP) System::Print("DPAD UP");
    if (joysticks[0]->DPAD_DOWN) System::Print("DPAD DOWN");
    if (joysticks[0]->DPAD_LEFT) System::Print("DPAD LEFT");
    if (joysticks[0]->DPAD_RIGHT) System::Print("DPAD RIGHT");
    
    for (int b = 0; b < sizeof(joysticks[0]->Button) / sizeof(*joysticks[0]->Button); b++) {
    if (joysticks[0]->Button[b] == true) {
    System::Print("Button pressed: " + std::to_string(B));
    }
    }
    
    if (joysticks[0]->trigger_left > 0)
    System::Print("Trigger left: " + std::to_string(joysticks[0]->trigger_left));
    if (joysticks[0]->trigger_right > 0)
    System::Print("Trigger right: " + std::to_string(joysticks[0]->trigger_right));
    
    }
    
    
    
    
    Leadwerks::Time::Update();
    world->Update();
    world->Render();
    context->Sync(false);
    
    return true;
    }
    

     

     

     

    Game_Controller.h

    /*
    Game controller class using SDL2
    - Added better support for XInput.
    - Button remapping.
    - Automatic re-acquiring when controller is unplugged/replugged.
    
    Download SDL2 and copy the SDL2-2.0.3 folder in your Source directory.
    Add SDL2.lib to your project and copy SDL2.dll where your executable is.
    */
    
    
    
    #include "Leadwerks.h"
    #include "SDL2-2.0.3/include/SDL.h"
    #undef main
    
    
    
    class Game_Controller {
    private:
    SDL_Joystick*	 m_joy;
    SDL_Event		 m_event;
    uint8			 m_total_joysticks;
    uint8			 m_index;
    std::string	 m_name;
    int16			 m_threshold;
    bool			 m_xinput;
    uint8			 m_mapped_buttons[32];
    bool			 m_auto_reacquire;
    bool			 m_reacquire_alternate_controller;
    
    
    uint8 FindControllerByName(std::string controller_name) {
    SDL_JoystickUpdate();
    
    int8 alternate_controller = -1;
    for (int c = 0; c < SDL_NumJoysticks(); c++) {
    SDL_Joystick* joy = SDL_JoystickOpen(c);
    if (joy) {
    if (SDL_JoystickName(joy) == m_name || controller_name == "") {
    //System::Print("Joystick found, reacquiring " + m_name);
    return c;
    }
    else if (m_reacquire_alternate_controller == true) {
    if (alternate_controller == -1)
    alternate_controller = c; // Use another controller if the one we're looking for can't be found //
    }
    SDL_JoystickClose(joy);
    }
    joy = NULL;
    }
    
    return alternate_controller;
    }
    
    
    public:
    Game_Controller() { m_index = -1; }
    ~Game_Controller() { Close(); }
    
    bool DPAD_UP, DPAD_DOWN, DPAD_LEFT, DPAD_RIGHT;
    bool AXIS_UP, AXIS_DOWN, AXIS_LEFT, AXIS_RIGHT;
    int16 axis_x, axis_y;
    uint8 trigger_left, trigger_right;
    bool Button[32];
    
    bool Init(uint8 index, int16 axis_threshold, bool auto_require, bool reacquire_alternate_controller) {
    if (index < 0 || index > SDL_NumJoysticks() - 1)
    return false;
    
    m_total_joysticks = SDL_NumJoysticks();
    m_index = index;
    m_threshold = axis_threshold;
    m_xinput = false;
    m_auto_reacquire = auto_require;
    m_reacquire_alternate_controller = reacquire_alternate_controller;
    
    DPAD_UP = false, DPAD_DOWN = false, DPAD_LEFT = false, DPAD_RIGHT = false;
    AXIS_UP = false, AXIS_DOWN = false, AXIS_LEFT = false, AXIS_RIGHT = false;
    
    for (int b = 0; b < sizeof(Button) / sizeof(*Button); b++) {
    Button[b] = false;
    m_mapped_buttons[b] = b;
    }
    
    trigger_left = 0;
    trigger_right = 0;
    axis_x = 0;
    axis_y = 0;
    
    if (m_joy)
    m_joy = NULL;
    
    SDL_JoystickEventState(SDL_ENABLE);
    m_joy = SDL_JoystickOpen(index);
    if (m_joy) {
    m_name = SDL_JoystickName(m_joy);
    if (m_name.length() > 0) {
    if (m_name.find("XInput") == 0) { // XInput devices have different button mapping //
    m_xinput = true;
    m_mapped_buttons[5] = 8; // select
    m_mapped_buttons[4] = 9; // start
    m_mapped_buttons[8] = 4;
    m_mapped_buttons[9] = 5;
    m_mapped_buttons[10] = 0;
    m_mapped_buttons[11] = 1;
    m_mapped_buttons[13] = 2;
    m_mapped_buttons[12] = 3;
    }
    
    }
    return true;
    }
    
    return false;
    }
    
    bool Reacquire() {
    m_total_joysticks = SDL_NumJoysticks();
    Close();
    
    if (m_auto_reacquire == true && m_total_joysticks > 0 && m_name.length() > 0) {
    uint8 index = FindControllerByName(m_name);
    if (index > -1) {
    Init(index, m_threshold, m_auto_reacquire, m_reacquire_alternate_controller);
    return true;
    }
    }
    return false;
    }
    
    void Close() {
    if (m_index > -1) {
    if (m_joy) {
    SDL_JoystickClose(m_joy);
    m_joy = NULL;
    }
    }
    }
    
    std::string GetName() {
    return m_name;
    }
    
    
    void ProcessEvents() {
    SDL_JoystickUpdate();
    if (SDL_NumJoysticks() != m_total_joysticks) // Controller changes detected, attempt to re-acquire //
    Reacquire();
    
    
    if (m_joy) {
    if (SDL_JoystickGetAttached(m_joy)) {
    
    while (SDL_PollEvent(&m_event))
    {
    switch (m_event.type) {
    case SDL_JOYAXISMOTION:
    
    //if (m_event.jaxis.which == m_index) {
    if (m_event.jaxis.axis == 0) {
    if (m_event.jaxis.value < -m_threshold) AXIS_LEFT = true;
    if (m_event.jaxis.value > m_threshold) AXIS_RIGHT = true;
    if (m_event.jaxis.value > -m_threshold && m_event.jaxis.value < m_threshold) {
    AXIS_LEFT = false;
    AXIS_RIGHT = false;
    }
    axis_x = m_event.jaxis.value;
    }
    if (m_event.jaxis.axis == 1) {
    if (m_event.jaxis.value < -m_threshold) AXIS_UP = true;
    if (m_event.jaxis.value > m_threshold) AXIS_DOWN = true;
    if (m_event.jaxis.value > -m_threshold && m_event.jaxis.value < m_threshold) {
    AXIS_UP = false;
    AXIS_DOWN = false;
    }
    axis_y = m_event.jaxis.value;
    }
    
    //if (m_event.cbutton.which == m_index) {
    if (m_event.cbutton.button == 4) {
    Button[m_mapped_buttons[6]] = (m_event.button.button > 0); // Left trigger
    trigger_left = m_event.button.button;
    }
    if (m_event.cbutton.button == 5) {
    Button[m_mapped_buttons[7]] = (m_event.button.button > 0); // Right trigger
    trigger_right = m_event.button.button;
    }
    //}
    break;
    //}
    
    case SDL_JOYHATMOTION:
    //if (m_event.jaxis.which == m_index) {
    DPAD_UP = false;
    DPAD_DOWN = false;
    DPAD_LEFT = false;
    DPAD_RIGHT = false;
    if (m_event.jhat.value & SDL_HAT_UP) DPAD_UP = true;
    if (m_event.jhat.value & SDL_HAT_DOWN) DPAD_DOWN = true;
    if (m_event.jhat.value & SDL_HAT_LEFT) DPAD_LEFT = true;
    if (m_event.jhat.value & SDL_HAT_RIGHT) DPAD_RIGHT = true;
    //}
    break;
    
     case SDL_JOYBUTTONDOWN:
    //if (m_event.jaxis.which == m_index) {
    if (m_xinput) {
    if (m_event.jbutton.button < 4) { // Directional pad (hat) on Xbox controllers are recognized as buttons //
    if (m_event.jbutton.button == 0) DPAD_UP = true;
    if (m_event.jbutton.button == 1) DPAD_DOWN = true;
    if (m_event.jbutton.button == 2) DPAD_LEFT = true;
    if (m_event.jbutton.button == 3) DPAD_RIGHT = true;
    }
    else {
    Button[m_mapped_buttons[m_event.jbutton.button]] = true;
    }
    }
    else {
    Button[m_mapped_buttons[m_event.jbutton.button]] = true;
    }
    //}
    break;
    
    
     case SDL_JOYBUTTONUP:
    //if (m_event.jaxis.which == m_index) {
    if (m_xinput) {
    if (m_event.jbutton.button < 4) {
    if (m_event.jbutton.button == 0) DPAD_UP = false;
    if (m_event.jbutton.button == 1) DPAD_DOWN = false;
    if (m_event.jbutton.button == 2) DPAD_LEFT = false;
    if (m_event.jbutton.button == 3) DPAD_RIGHT = false;
    }
    else {
    Button[m_mapped_buttons[m_event.jbutton.button]] = false;
    }
    }
    else {
    Button[m_mapped_buttons[m_event.jbutton.button]] = false;
    }
    //}
    break;
    
    }
    
    }
    
    }
    
    }
    
    }
    
    };
    

  10. I've been writing a c++ class using SDL in the last few days and it's almost finished. There were issues with my xbox controller, keys aren't mapped the same as regular controllers but i managed to fix it and implement a button mapping feature and now it behaves like normal controllers. It can automatically re-acquire controllers that are unplugged/replugged.

     

    I will post the code once i'ts done, after that, i'll add lua support.

    • Upvote 1
  11. why do you delete new_entity if != null? you created a new one in memory then you delete the memory.

    Damn that was meant for an Entity class, which was part of my Map_Entity class previously but removed because accessing members or methods within the script caused a crash and forgot to get rid of that delete.

     

    Thanks again for pointing out my silly mistake! laugh.png

  12. In App.h

    Map_Entity* map_characters[100];
    

     

     

    In App.cpp (App::Start)

    entities[0] = Model::Load("Models/Characters/Dwarf/dwarfmale_run.mdl");
    map_characters[0] = helpers->InitModel(entities[0], ENTITY_TYPE::PC, "Rygar", Vec3(0, 0, -5.73), 0.02, 1, COLLISION_TRIGGER, Entity::CharacterPhysics, "dwarfmale_run_bone_64", "dwarfmale_run_bone_LFingerRing");
    IScript* script = new PlayerScript(entities[0], map_characters[0], window);
    

     

     

    In Helpers.h

    #ifndef _HELPERS_H
    #define _HELPERS_H
    
    using namespace Leadwerks;
    
    class Map_Entity;
    
    enum ENTITY_TYPE : uint8 {
    NPC = 0,
    PC = 1
    };
    
    class Helpers {
    public:
    Helpers() {}
    Map_Entity* InitModel(Entity* entity, ENTITY_TYPE entity_type, std::string name, Vec3 position, float scale, float mass,
    const int collision_type,
    const int physics_mode, std::string boneWeapon, std::string boneShield);
    
    };
    #endif
    

     

    In Helpers.cpp

    #include "../entities/entity.h"
    #include "helpers.h"
    using namespace Leadwerks;
    
    
    
    Map_Entity* Helpers::InitModel(Entity* entity, ENTITY_TYPE entity_type, std::string name, Vec3 position,
    float scale, float mass, const int collision_type, const int physics_mode, std::stringboneWeapon, std::string boneShield) {
    
    Map_Entity* new_entity = new Map_Entity();
    
    if (new_entity != NULL) {
    delete new_entity;
    }
    
    if (entity != NULL) {
    entity->SetScale(scale);
    entity->SetMass(mass);
    entity->SetPosition(position);
    entity->SetGravityMode(true);
    entity->SetCollisionType(collision_type);
    entity->SetPhysicsMode(physics_mode);
    entity->Hide();
    
    new_entity->boneWeapon = boneWeapon;
    new_entity->boneShield = boneShield;
    new_entity->aniSpeed = 35;
    new_entity->entity_type = entity_type;
    new_entity->name = name;
    new_entity->set_mass_delay = 0;
    new_entity->anim_length[0] = entity->GetAnimationLength("Run");
    new_entity->anim_starttime = 0;
     for (int aa = 0; aa < sizeof(new_entity->anim_speeds) / sizeof(*new_entity->anim_speeds); aa++) {
    new_entity->anim_speeds[aa] = 30;
    }
    new_entity->speed = 5;
    
    return new_entity;
    }
    
    
    return NULL;
    };
    

  13. I'm passing several objects in my IScript initializer:

    class PlayerScript : public IScript
    {
    public:
    PlayerScript(Entity* e, Map_Entity* me, Window* w) :IScript() {
    m_entity = e;
    map_entity = me;
    m_window = w;
    }
    
    void Collision(Entity* entity, float* position, float* normal, float speed) {
    }
    

     

     

    Map_Entity is a simple class with variables that i'm passing to the script when initialized:

    class Map_Entity {
    public:
    float speed;
    std::string boneWeapon;
    std::string boneShield;
    uint8 anim_speeds[5];
    };
    

     

    Problem is, the Map_Entity data passed to the script doesn't retain their values after exiting the constructor method. I could copy every values manually or do a memcpy but i'd rather not if i don't have to. I've been reading for hours and looking at a lot of examples and still can't figure it out.

  14. Here's how both classes look like now:

    class IScript
    {
    protected:
    Entity* ent;
    public:
    IScript() {}
    virtual void Collision(Entity* entity, float* position, float* normal, float speed) = 0;
    virtual void UpdateWorld() = 0;
    virtual void UpdatePhysics() = 0;
    virtual void SetEntity(Entity* entity) = 0;
    };
    

     

    class PlayerScript : public IScript
    {
    public:
    PlayerScript() :IScript() {}
    void Collision(Entity* entity, float* position, float* normal, float speed) {
    
    }
    
    void UpdateWorld() {
    }
    
    void UpdatePhysics() {
    }
    
    void SetEntity(Entity* entity) {
    ent = entity;
    }
    
    
    };
    

    I've changed my constructor for PlayerScript(Entity* e) :IScript() { ent = e; } and removed SetEntity method and now using IScript* script = new PlayerScript(entities[0]); like you suggested.

     

    Thanks!

×
×
  • Create New...