MVP matrixy wariują open gl

Odpowiedz Nowy wątek
2018-01-10 23:00
0

Cześć! Próbuję zrobić efekt kostki i na razie zatrzymałem się na przechylaniu tekstury, bo problem polega na tym, że gdy odpalam aplikację tekstura zaczyna wariować
tak wygląda while loop

        glm::mat4 model;
        model = glm::rotate(model, glm::radians(-55.0f), glm::vec3(1.0, 0.0, 0.0));
 
        glm::mat4 view;
        view = glm::translate(view, glm::vec3(0.0f, 0.0f, -3.0f));
 
        glm::mat4 projection;
        projection = glm::perspective(glm::radians(45.0f), 1280.0f / 720.0f, 0.1f, 100.0f);
 
        // Od razu przypisuje uniform do programu shadera
        GLint u_model = shader.GetUniformLocation("u_model");
        GLint u_view = shader.GetUniformLocation("u_view");
        GLint u_projection = shader.GetUniformLocation("u_projection");
 
        glUniformMatrix4fv(u_model, 1, GL_FALSE, glm::value_ptr(model));
        glUniformMatrix4fv(u_view, 1, GL_FALSE, glm::value_ptr(view));
        glUniformMatrix4fv(u_projection, 1, GL_FALSE, glm::value_ptr(projection));
 
        Rect destRect = { -0.5, -0.5, 1.0, 1.0 };
        Rect uvRect = { 0.0f, 0.0f, 1.0f, 1.0f };
 
        texture.Draw(destRect, uvRect);
 
        window.SwapWindow();
#version 330 core
 
layout (location = 0) in vec3 a_position;
layout (location = 1) in vec4 a_color;
layout (location = 2) in vec2 a_uv;
 
out vec2 v_UV;
out vec4 v_Color;
out vec2 v_Position;
 
uniform mat4 u_model;
uniform mat4 u_view;
uniform mat4 u_projection;
 
void main()
{
    gl_Position = u_projection * u_view * u_model * vec4(a_position, 1.0);
 
    v_Position = a_position;
    v_Color = a_color;
    v_UV = vec2(a_uv.x, 1 - a_uv.y);
}

Takie właśnie wygibasy

Zrobiłem sobie klasę kamery (do gry 2D) i przy glm::ortho wszystko gra i buczy, a jak próbuje wejść w 3d to takie nienormalne rzeczy się robią.

W jaki sposób to naprawić?

edytowany 6x, ostatnio: SiemkaElkoTszyPiencZerko, 2018-01-10 23:11

Pozostało 580 znaków

2018-01-11 20:30
0

main

int main(int argc, char*args[])
{
    MainGame mainGame;
    mainGame.GameLoop();
 
    return 0;
}
 
MainGame::MainGame()
{
    //Tworzy okno - nazwa, w, h, parametr, vsync
    window.CreateWindow("openGL", 1280, 720, SDL_WINDOW_OPENGL, true);
 
    texture.Initialize();
    texture.LoadFromFile("image.png");
 
    std::string vertex = shader.LoadFromFile("vertex.shader");
    std::string fragment = shader.LoadFromFile("fragment.shader");
 
    shader.CreateShaderProgram();
    shader.CreateShaders(vertex.c_str(), fragment.c_str());
    shader.UseShaderProgram();
 
    GLint u_textureSampler = shader.GetUniformLocation("u_textureSampler");
    glUniform1f(u_textureSampler, 0);
 
    glClearColor(0.0f, 0.0f, 0.0f, 255.0f);
}
 
void MainGame::GameLoop()
{
    while (!quit) 
    {
        while (SDL_PollEvent(&event)) 
        {
            if (event.type == SDL_QUIT) 
            {
                SDL_Quit();
                exit(0);
            }
        }
 
        glClearDepth(1.0f);
        glEnable(GL_DEPTH_TEST);  
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
 
        glm::mat4 model;
 
        model = glm::translate(model, glm::vec3(0.0f, 0.0f, -3.0f));
        model = glm::rotate(model, glm::radians(-55.0f), glm::vec3(1.0, 0.0, 0.0));
 
        glm::mat4 projection;
        projection = glm::perspective(glm::radians(45.0f), 1280.0f / 720.0f, 0.1f, 100.0f);
 
        GLint u_model = shader.GetUniformLocation("u_model");
        GLint u_projection = shader.GetUniformLocation("u_projection");
 
        glUniformMatrix4fv(u_model, 1, GL_FALSE, glm::value_ptr(model));
        glUniformMatrix4fv(u_projection, 1, GL_FALSE, glm::value_ptr(projection));
 
        Rect destRect = { -0.5, -0.5, 1.0, 1.0 };
        Rect uvRect = { 0.0f, 0.0f, 1.0f, 1.0f };
 
        texture.Begin();
        texture.Draw(destRect, uvRect);
        texture.End();
        texture.Render();
 
        window.Swap();
    }
}

Texture

    Texture::Texture() {}
 
    Texture::~Texture() {}
 
    void Texture::Initialize()
    {
        sprite.CreateVertexArray();
    }
 
    void Texture::LoadFromFile(const std::string &filePath)
    {
        texture = textureCache.getTexture(filePath);
 
        w = textureCache.getWidth();
        h = textureCache.getHeight();
    }
 
    void Texture::Begin()
    {
        sprite.Begin();
    }
 
    void Texture::Draw(Rect destRect, Rect uvRect, ColorRGBA8 color)
    {
        glActiveTexture(GL_TEXTURE0);
        sprite.Draw(destRect, uvRect, texture, color);
    }
 
    void Texture::End()
    {
        sprite.End();
    }
 
    void Texture::Render()
    {
        sprite.Render();
    }
 
    void Texture::DrawBDER(Rect destRect, Rect uvRect, ColorRGBA8 color)
    {
        Begin();
        Draw(destRect, uvRect, color);
        End();
        Render();
    }
 
    int Texture::getWidth()
    {
        return w;
    }
 
    int Texture::getHeight()
    {
        return h;
    }
 
//----------------------------------------------------------------------------------------------------------------
 
    TextureCache::TextureCache() :
        w(0), h(0)
    {}
 
    TextureCache::~TextureCache() { textureMap.clear(); }
 
    GLuint TextureCache::LoadFromFile(const std::string & filePath)
    {
        textureMap.clear();
 
        GLuint texture = 0;
 
        SDL_Surface* surface = IMG_Load(filePath.c_str());
 
        glGenTextures(1, &texture);
        glBindTexture(GL_TEXTURE_2D, texture);
 
        int Format;
        if(surface->format->BytesPerPixel == 4) {
            Format = GL_RGBA;
        } else {
            Format = GL_RGB;
        }
        w = surface->w;
        h = surface->h;
 
        glTexImage2D(GL_TEXTURE_2D, 0, Format, w, h, 0, Format, GL_UNSIGNED_BYTE, surface->pixels);
 
        SDL_FreeSurface(surface);
 
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
 
        glGenerateMipmap(GL_TEXTURE_2D);
 
        glBindTexture(GL_TEXTURE_2D, 0);
 
        return texture;
    }
 
    GLuint TextureCache::getTexture(const std::string &filePath)
    {
        auto mit = textureMap.find(filePath);
 
        if (mit == textureMap.end()) 
        {
            GLuint newTexture = LoadFromFile(filePath);
 
            textureMap[filePath] = newTexture;
 
            return newTexture;
        }
        return mit->second;
    }
 
    int TextureCache::getWidth()
    {
        return w;
    }
 
    int TextureCache::getHeight()
    {
        return h;
    }

Sprite.h

enum class SortType
    {
        NONE, FRONT_TO_BACK, BACK_TO_FRONT, TEXTURE
    };
 
    class Glyph
    {
    public:
        Glyph() {}
        Glyph(const Rect &destRect, const Rect &uvRect, GLuint Texture, const ColorRGBA8 &color = { 255, 255, 255, 255 });
 
        GLuint texture;
        float depth;
 
        Vertex topLeft;
        Vertex topRight;
        Vertex bottomLeft;
        Vertex bottomRight;
    };
 
    class RenderBatch
    {
    public:
        RenderBatch(GLuint Offset, GLuint NumVertices, GLuint Texture) :
            offset(Offset), numVertices(NumVertices), texture(Texture)
        {}
        ~RenderBatch() {}
 
        GLuint offset;
        GLuint numVertices;
        GLuint texture;
    };
 
    class Sprite
    {
    public:
        Sprite();
        ~Sprite();
 
        void CreateVertexArray();
        void Free();
 
        void Begin(SortType sort = SortType::TEXTURE);
        void Draw(const Rect &destRect, const Rect &uvRect, GLuint texture, const ColorRGBA8 &color);
        void End();
        void Render();
    private:
        void CreateRenderBatches();
        GLuint vbo;
        GLuint vao;
        GLuint ebo;     
 
        void Sort();
        static bool compereFrontToBack(Glyph *a, Glyph *b);
        static bool compereBackToFront(Glyph *a, Glyph *b);
        static bool compereTexture(Glyph *a, Glyph *b);
 
        std::vector<Glyph> glyphs; // Actual glyphs
        std::vector<Glyph*> glyphPointers; // For sorting
        std::vector<RenderBatch> renderBatches;
 
        SortType sortType;
    };

sprite.h

 
    Glyph::Glyph(const Rect & destRect, const Rect & uvRect, GLuint Texture, const ColorRGBA8 &color) :
        texture(Texture)
    {
        topLeft.color = color;
        topLeft.setPosition(destRect.x, destRect.y + destRect.h);
        topLeft.setUV(uvRect.x, uvRect.y + uvRect.h);
 
        bottomLeft.color = color;
        bottomLeft.setPosition(destRect.x, destRect.y);
        bottomLeft.setUV(uvRect.x, uvRect.y);
 
        bottomRight.color = color;
        bottomRight.setPosition(destRect.x + destRect.w, destRect.y);
        bottomRight.setUV(uvRect.x + uvRect.w, uvRect.y);
 
        topRight.color = color;
        topRight.setPosition(destRect.x + destRect.w, destRect.y + destRect.h);
        topRight.setUV(uvRect.x + uvRect.w, uvRect.y + uvRect.h);
    }
 
Sprite::Sprite() : vbo(0), vao(0), ebo(0)
    {}
 
    Sprite::~Sprite() { Free(); }
 
    void Sprite::Free()
    {
        glDeleteBuffers(1, &vbo);
        glDeleteBuffers(1, &ebo);
        glDeleteVertexArrays(1, &vao);
 
        renderBatches.clear();
 
        for (const auto & gp : glyphPointers) {
            delete gp;
        }
        glyphPointers.clear();
 
        glyphs.clear();
    }
 
    void Sprite::Begin(SortType sort)
    {
        glActiveTexture(GL_TEXTURE0);
        sortType = sort;
        renderBatches.clear();
        glyphPointers.clear();
        glyphs.clear();
    }
 
    void Sprite::End()
    {
        glyphPointers.resize(glyphs.size());
        for (size_t i = 0; i < glyphs.size(); i++) 
        {
            glyphPointers[i] = &glyphs[i];
        }
        Sort();
        CreateRenderBatches();
    }
 
    void Sprite::Draw(const Rect &destRect, const Rect &uvRect, GLuint texture, const ColorRGBA8 &color)
    {
        glyphs.emplace_back(destRect, uvRect, texture, color);
    }
 
    void Sprite::Render()
    {
        glBindVertexArray(vao);
        for (const auto & rb : renderBatches) 
        {
            //glEnable(GL_CULL_FACE);
            //glCullFace(GL_FRONT);
            //glFrontFace(GL_CW);
 
            glBindTexture(GL_TEXTURE_2D, rb.texture);
            glDrawArrays(GL_TRIANGLES, rb.offset, rb.numVertices);
        }
        glBindVertexArray(0);
        glBindTexture(GL_TEXTURE_2D, 0);
    }
 
    void Sprite::CreateRenderBatches()
    {
        std::vector<Vertex> verticies;
        verticies.resize(glyphPointers.size() * 6);
        if (glyphPointers.empty()) return;
 
        int offset = 0;
        int cv = 0; // current vertex;
 
        renderBatches.emplace_back(offset, 6, glyphPointers[0]->texture);
        verticies[cv++] = glyphPointers[0]->topLeft;
        verticies[cv++] = glyphPointers[0]->bottomLeft;
        verticies[cv++] = glyphPointers[0]->bottomRight;
        verticies[cv++] = glyphPointers[0]->bottomRight;
        verticies[cv++] = glyphPointers[0]->topRight;
        verticies[cv++] = glyphPointers[0]->topLeft;
        offset += 6;
 
        for (int i = 1; i < glyphPointers.size(); i++) 
        {
            if (glyphPointers[i]->texture != glyphPointers[i - 1]->texture)
             {
                renderBatches.emplace_back(offset, 6, glyphPointers[i]->texture);
            } 
            else 
            {
                renderBatches.back().numVertices += 6;
            }
 
            verticies[cv++] = glyphPointers[i]->topLeft;
            verticies[cv++] = glyphPointers[i]->bottomLeft;
            verticies[cv++] = glyphPointers[i]->bottomRight;
            verticies[cv++] = glyphPointers[i]->bottomRight;
            verticies[cv++] = glyphPointers[i]->topRight;
            verticies[cv++] = glyphPointers[i]->topLeft;
            offset += 6;
        }
 
        glBindBuffer(GL_ARRAY_BUFFER, vbo);
        glBufferData(GL_ARRAY_BUFFER, verticies.size() * sizeof(Vertex), nullptr, GL_DYNAMIC_DRAW);
        glBufferSubData(GL_ARRAY_BUFFER, 0, verticies.size() * sizeof(Vertex), verticies.data());
 
        glBindBuffer(GL_ARRAY_BUFFER, 0);
    }
 
    void Sprite::CreateVertexArray()
    {
        glGenVertexArrays(1, &vao);
        glBindVertexArray(vao);
 
        glGenBuffers(1, &vbo);
        glBindBuffer(GL_ARRAY_BUFFER, vbo);
 
        glGenBuffers(1, &ebo);
        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo);
 
        glEnableVertexAttribArray(0);
        glEnableVertexAttribArray(1);
        glEnableVertexAttribArray(2);
 
        glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)offsetof(Vertex, position));
        glVertexAttribPointer(1, 4, GL_FLOAT, GL_TRUE, sizeof(Vertex), (void*)offsetof(Vertex, color));
        glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)offsetof(Vertex, uv));
 
        glBindVertexArray(0);
    }
 
    void Sprite::Sort()
    {
        switch (sortType)
        {
            case SortType::BACK_TO_FRONT: std::stable_sort(glyphPointers.begin(), glyphPointers.end(), compereBackToFront); break;
            case SortType::FRONT_TO_BACK: std::stable_sort(glyphPointers.begin(), glyphPointers.end(), compereFrontToBack); break;
            case SortType::TEXTURE:       std::stable_sort(glyphPointers.begin(), glyphPointers.end(), compereTexture);     break;
        }
    }
 
    bool Sprite::compereFrontToBack(Glyph* a, Glyph* b)
    {
        return a->depth < b->depth;
    }
 
    bool Sprite::compereBackToFront(Glyph* a, Glyph* b)
    {
        return a->depth > b->depth;
    }
 
    bool Sprite::compereTexture(Glyph* a, Glyph* b)
    {
        return a->texture < b->texture;
    }

Teraz jestem w trakcie zmieniania z samych vertexów na index buffer object, stąd te kawałki dodatkowego kodu.

edytowany 1x, ostatnio: SiemkaElkoTszyPiencZerko, 2018-01-11 20:35

Pozostało 580 znaków

2018-01-12 22:21
0

Dziwny podział na klasy, tekstura powinna być raczej składową sprite'a a nie na odwrót. Nie wiem po co jest textura i textureCache, wystarczy jedna klasa tekstura w której załadujesz obrazek i przechowasz zmienne w i h (w zasadzie to tylko nazewnictwo czasami, ale dziwnie się czyta).

Trochę mało to wszystko czytelne, spróbuj jeszcze raz jakoś czytelniej rozpisać, mały przykład: https://pastebin.com/1kFLwk0K (może nie taki mały, bo się bawiłem stencil bufferem żeby uzyskać efekt lustra).

Co do tego czemu nie działa nie mogę się doszukać.

edytowany 1x, ostatnio: czaffik, 2018-01-12 22:22

Pozostało 580 znaków

2018-01-12 22:35
1
czaffik napisał(a):

za każdym obrotem pętli wartość model się cały czas zmieniała w efekcie co obrót kąt był coraz większy.

W tym kodzie w ogóle jest dużo rzeczy niepotrzebnie wykonywanych wielokrotnie. Choć to raczej nie zaszkodzi, po prostu zmniejsza wydajność – nawet jeśli nie w przypadku prostej sceny, warto mieć nawyk unikania powtarzania tych samych komend:

           glEnable(GL_CULL_FACE);
           glCullFace(GL_FRONT);
           glFrontFace(GL_CW);

— nie ma powodu by to wywoływać dla każdego rysowanego obiektu. Jeśli nigdy nie zmieniasz tych parametrów, wystarczy raz przy inicjalizacji.

       glBindVertexArray(0);
       glBindTexture(GL_TEXTURE_2D, 0);

— odbindowywanie VAO i tekstury niczemu właściwie nie służy. VAO – jeśli używasz tylko jednego – wystarczy zabindować raz, przy inicjalizacji. Teksturę tylko gdy zmieniasz.

Pamiętaj że OpenGL to maszyna stanów. glEnable na czymś wykonane raz zachowuje ważność aż nie zostanie zmienione. Nie trzeba całego stanu odnawiać przy każdym obiekcie czy nawet przy każdej rysowanej klatce.

       glClearDepth(1.0f);
       glEnable(GL_DEPTH_TEST);  

— j.w.

       glActiveTexture(GL_TEXTURE0);

— jeśli nie używasz multiteksturowania to w ogóle nie potrzebujesz glActiveTexture. Jeśli używasz wielu tekstur na raz, to może być potrzebne do ustawiania parametrów tych tekstur, ale nie do rysowania.

        GLint u_model = shader.GetUniformLocation("u_model");
        GLint u_projection = shader.GetUniformLocation("u_projection");

— to też powinno być w części inicjalizacyjnej, nie w pętli rysującej.

edytowany 3x, ostatnio: Azarien, 2018-01-12 23:05
u_model to może zostać w pętli, zawsze można się pokusić o dynamiczną zmianę tego parametru, jednak u_projection to faktycznie nie ma żadnego sensu umieszczać w pętli, no chyba że będziemy dynamicznie zmieniać perspektywę, co raczej nie jest spotykane. - czaffik 2018-01-13 11:21
@czaffik: można zmieniać wartość samego uniforma, ale „lokacja” zwracana przez GetUniformLocation nie będzie ulegać zmianie, jest stała dla danego shadera. - Azarien 2018-01-13 13:21
no tak, pomyliło mi się z ustawianiem uniforma. - czaffik 2018-01-13 14:25

Pozostało 580 znaków

2018-01-12 23:17
0
GLint u_model = shader.GetUniformLocation("u_model");
 GLint u_projection = shader.GetUniformLocation("u_projection");

— to też powinno być w części inicjalizacyjnej, nie w pętli rysującej.

Dobrze wiedziec. W poradniku bylo w petli

glActiveTexture(GL_TEXTURE0);

— jeśli nie używasz multiteksturowania to w ogóle nie potrzebujesz glActiveTexture. Jeśli używasz wielu tekstur na raz, to może być potrzebne do ustawiania parametrów tych tekstur, ale nie do rysowania.

Jestem tego swiadomy.

glBindVertexArray(0);
glBindTexture(GL_TEXTURE_2D, 0);

— odbindowywanie VAO i tekstury niczemu właściwie nie służy. VAO – jeśli używasz tylko jednego – wystarczy zabindować raz, przy inicjalizacji. Teksturę tylko gdy zmieniasz.

czyli z metody render po prostu wyrzucic to

edytowany 1x, ostatnio: SiemkaElkoTszyPiencZerko, 2018-01-12 23:17

Pozostało 580 znaków

2018-01-12 23:43
0

Dziwny podział na klasy, tekstura powinna być raczej składową sprite'a a nie na odwrót.

To znaczy?

Nie wiem po co jest textura i textureCache

texture cache jest taką małą klasą w pliku Texture.h. Wygodniej mi się tak nazywa i korzysta po prostu.

Trochę mało to wszystko czytelne

Co dokładnie nie jest czytelne? Klasa Glyph rysuje nam prostokąt, robię tablice pointerów na glyph do sortowania, a bez pointera do prawdziwego prostokąta. Begin wybiera metode sortowania i czyści resztę. End dodaje prawdziwy glyph do pointerów, sortuje i tworzy vertexy i przesyła je do gpu (chyba tak to działa, jestem w tym nowy). Render rysuje obiekt. Nie wiem zbytnio co moze byc mało czytelne. Chociaż może można sie troche zaplątać.

edytowany 1x, ostatnio: SiemkaElkoTszyPiencZerko, 2018-01-12 23:44

Pozostało 580 znaków

2018-01-12 23:58
0

Trochę to przekombinowane jak na prosty program typu efekt kostki…
Zacznij może od prostego po prostu narysowania tej kostki.
Do tego wystarczy ci statyczna tablica 8 wierzchołków i glDrawArrays. Potem dodaj teksturę.
Jak to zadziała dopiero wtedy stopniowo baw się w podział na klasy, jakieś render batche, sortowanie itp.
W obecnym kodzie naprawdę trudno dojść dlaczego nie działa – tyle tego jest.

edytowany 2x, ostatnio: Azarien, 2018-01-13 00:11

Pozostało 580 znaków

2018-01-13 11:35
0

@SiemkaElkoTszyPiencZerko: klasa Tekstura u ciebie powinna się raczej nazywać prostokąt albo sprite, tymczasem zawiera w sobie i teksturę (która nazywa się tekstureCache i sprite'a który tworzy siatkę i przekazuje ją do shadera, a wystarczy sama klasa sprite która zawiera w sobie teksturę którą nałożysz na prostokąt, a klasa Glyph całkiem już zaciemnia obraz, pamiętaj że im więcej masz takich podziałów kiedy ich nie potrzeba tym trudniej dojść o co chodzi.

Pozostało 580 znaków

2018-01-13 14:27
0
Azarien napisał(a):

Trochę to przekombinowane jak na prosty program typu efekt kostki…
Zacznij może od prostego po prostu narysowania tej kostki.
Do tego wystarczy ci statyczna tablica 8 wierzchołków i glDrawArrays. Potem dodaj teksturę.
Jak to zadziała dopiero wtedy stopniowo baw się w podział na klasy, jakieś render batche, sortowanie itp.
W obecnym kodzie naprawdę trudno dojść dlaczego nie działa – tyle tego jest.

To tak właśnie zrobiłem.

struct Rect {
    float x, y;
    float w, h;
};
struct Position {
    float x, y;
};
 
struct UV {
    float u, v;
};
 
struct ColorRGBA {
    GLubyte r, g, b, a;
};
class VertexData
{
public:
    VertexData();
    ~VertexData();
 
    void setPosition(float x, float y);
    void setcolor(ColorRGBA color);
    void setUV(float u, float v);
 
    UV uv;
    ColorRGBA color;
    Position position;
};
#pragma once
 
#include "VertexData.h"
#include <glew.h>
 
class Mesh
{
public:
    Mesh();
    ~Mesh();
    void CreateVertexArray();
 
    void CreateQuad(Rect destRect, Rect uvRect, ColorRGBA color);
 
    void Draw();
private:
    GLuint vao, vbo, ebo;
 
    VertexData vertex[4];
};
#include "Mesh.h"
 
Mesh::Mesh(){}
 
Mesh::~Mesh(){}
 
void Mesh::CreateVertexArray()
{
    glGenVertexArrays(1, &vao);
    glBindVertexArray(vao);
 
    glGenBuffers(1, &vbo);
    glBindBuffer(GL_ARRAY_BUFFER, vbo);
 
    glGenBuffers(1, &ebo);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo);
 
    glEnableVertexAttribArray(0);
    glEnableVertexAttribArray(1);
    glEnableVertexAttribArray(2);
 
    glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(VertexData), (void*)offsetof(VertexData, position));
    glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, sizeof(VertexData), (void*)offsetof(VertexData, uv));
    glVertexAttribPointer(2, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(VertexData), (void*)offsetof(VertexData, color));
 
    glBindVertexArray(0);
}
 
void Mesh::CreateQuad(Rect destRect, Rect uvRect, ColorRGBA color)
{
    vertex[0].color = color; // topleft
    vertex[0].setPosition(destRect.x, destRect.y + destRect.h);
    vertex[0].setUV(uvRect.x, uvRect.y + uvRect.h);
 
    vertex[1].color = color;
    vertex[1].setPosition(destRect.x, destRect.y); // bottom left
    vertex[1].setUV(uvRect.x, uvRect.y);
 
    vertex[2].color = color;
    vertex[2].setPosition(destRect.x + destRect.w, destRect.y); // bottom right
    vertex[2].setUV(uvRect.x + uvRect.w, uvRect.y);
 
    vertex[3].color = color;
    vertex[3].setPosition(destRect.x + destRect.w, destRect.y + destRect.h); // top right
    vertex[3].setUV(uvRect.x + uvRect.w, uvRect.y + uvRect.h);
 
    GLuint indices[6] = {
        0, 1, 2,
        2, 3, 0
    };
 
    glBindBuffer(GL_ARRAY_BUFFER, vbo);
    glBufferData(GL_ARRAY_BUFFER, 6 * sizeof(vertex), NULL, GL_STATIC_DRAW); // orphan the buffer
    glBufferSubData(GL_ARRAY_BUFFER, 0, 6 * sizeof(vertex), vertex);
 
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, 6 * sizeof(GLuint), NULL, GL_STATIC_DRAW); // orphan the buffer
    glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, 0, 6 * sizeof(GLuint), indices);
 
    //glBindBuffer(GL_ARRAY_BUFFER, 0);
}
 
void Mesh::Draw()
{
    glBindVertexArray(vao);
 
    //glEnable(GL_CULL_FACE);
    //glCullFace(GL_FRONT);
    //glFrontFace(GL_CW);
    glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, NULL);
 
    //glBindVertexArray(0);
}

I w mainie

    glm::mat4 model;
        model = glm::rotate(model, glm::radians(-55.0f), glm::vec3(1.0, 0.0, 0.0));
 
        glm::mat4 view;
        view = glm::translate(view, glm::vec3(0.0f, 0.0f, -3.0f));
 
        glm::mat4 projection;
        projection = glm::perspective(glm::radians(45.0f), 1280.0f / 720, 0.1f, 100.0f);
 
        GLint u_model = shader.GetUniformLocation("u_model");
        GLint u_view = shader.GetUniformLocation("u_view");
        GLint u_projection = shader.GetUniformLocation("u_projection");
 
        glUniformMatrix4fv(u_model, 1, GL_FALSE, glm::value_ptr(model));
        glUniformMatrix4fv(u_view, 1, GL_FALSE, glm::value_ptr(view));
        glUniformMatrix4fv(u_projection, 1, GL_FALSE, glm::value_ptr(projection));
 
        Rect destRect = { -0.5f, -0.5f, 1.0f, 1.0f };
        Rect uvRect = { 0.0f, 0.0f, 1.0f, 1.0f };
        ColorRGBA color = { 255, 255, 128, 0 };
 
        mesh.CreateQuad(destRect, uvRect, color);
        mesh.Draw();
 

Potem jeszcze zmieniałem z modelview i nadal taki sam efekt bez tekstury, bez sprite batcha. Chyba jest to dużo prościej zrobione.

edytowany 3x, ostatnio: SiemkaElkoTszyPiencZerko, 2018-01-13 14:33

Pozostało 580 znaków

2018-01-13 14:31
0
czaffik napisał(a):

@SiemkaElkoTszyPiencZerko: klasa Tekstura u ciebie powinna się raczej nazywać prostokąt albo sprite, tymczasem zawiera w sobie i teksturę (która nazywa się tekstureCache i sprite'a który tworzy siatkę i przekazuje ją do shadera, a wystarczy sama klasa sprite która zawiera w sobie teksturę którą nałożysz na prostokąt, a klasa Glyph całkiem już zaciemnia obraz, pamiętaj że im więcej masz takich podziałów kiedy ich nie potrzeba tym trudniej dojść o co chodzi.

Jak byś proponował wtedy to zrobić?

Pozostało 580 znaków

2018-01-13 15:25
0
  1. W Mesh::CreateQuad utworzyłeś bufory vbo i ebo ale nie stowarzyszyłeś z nimi żadnego vao, co prawda w Mesh::CreateVertexArray masz utworzone i zbindowane vao ale pod koniec funkcji masz glBindVertexArray(0); w funkcji Mesh::Draw masz:

    glBindVertexArray(vao);
    glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, NULL);

    problem w tym że w tym vao nie masz zapisanych żadnych informacji na temat werteksów które przepchnąłeś do vbo i ebo
    czyli przed tym:

    glBindBuffer(GL_ARRAY_BUFFER, vbo);
    glBufferData(GL_ARRAY_BUFFER, 6 * sizeof(vertex), NULL, GL_STATIC_DRAW); // orphan the buffer
    glBufferSubData(GL_ARRAY_BUFFER, 0, 6 * sizeof(vertex), vertex); 
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, 6 * sizeof(GLuint), NULL, GL_STATIC_DRAW); // orphan the buffer
    glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, 0, 6 * sizeof(GLuint), indices);

    powinno być to:

    glBindVertexArray(vao);
  2. Teraz możesz stworzyć klasę tekstury, np coś takiego:

    class Texture
    {
    public:
        Texture(std::string fileName);
        Texture(SDL_Surface *surface);
        virtual ~Texture();
     
        void bind() { glBindTexture(GL_TEXTURE_2D, id); }
     
    protected:
        void createFromFile(std::string fileName);
        void createFromSurface(SDL_Surface *surface);
        SDL_Surface* flipImage(SDL_Surface *surface);
     
        GLuint id;
     
    private:
    };

    i dorzucić ją do klasy Mesh.

edytowany 1x, ostatnio: czaffik, 2018-01-13 15:25

Pozostało 580 znaków

Odpowiedz
Liczba odpowiedzi na stronę

1 użytkowników online, w tym zalogowanych: 0, gości: 1, botów: 0