0

OpenGL で奇妙な問題が発生したようです。マップを大きくしすぎるまで (最大で 800x800 前後)、クラスですべてが正常に機能し、その後 OpenGL は何も描画しません。glGetBufferSubData を呼び出しましたが、頂点バッファとインデックス バッファの両方でデータが正しいように見えましたが、何も描画されていませんか? 最初は、コードのどこかでオーバーフローが発生していると想定していましたが、std::numeric_limits によると、頂点とインデックスのイテレータが (符号付き) int の最大サイズに近づいていないようです。私は OpenGL オブジェクトの周りに多くのラッパー クラスを使用していますが、それらは非常に単純で、通常は同等の OpenGL へのインライン呼び出しです。プリミティブ型の "M_" typedef についても同じです。以下は、私がレンダリングするメイン ループ、問題があると思われるクラス、および出力の 2 つのスクリーンショットです。

正しい出力: http://i.imgur.com/cvC1T7L.png

マップを展開した後の空白の出力: http://i.imgur.com/MmmNgj4.png

メインループ:

int main(){
//open window
Memento::MainWindow& main_window = Memento::MainWindow::GetInstance();
Memento::MainWindow::Init();
main_window.SetTitle("Memento");
main_window.Open();

//matrices
glmx_mat4 ortho_matrix = {};
glmx_mat4_ortho(0.0f, 800.0f, 600.0f, 0.0f, 5.0f, 25.0f, ortho_matrix);

glmx_mat4 modelview_matrix = {};
glmx_mat4_identity(modelview_matrix);

glmx_vec3 translate_vec = {0.0f, 0.0f, -10.0f};
glmx_mat4_translate(modelview_matrix, translate_vec, modelview_matrix);

glmx_mat4_multiply(ortho_matrix, modelview_matrix, ortho_matrix);

//shaders
Memento::GLShader default_vert_shader("default.vert", GL_VERTEX_SHADER);
default_vert_shader.Compile();

Memento::GLShader default_frag_shader("default.frag", GL_FRAGMENT_SHADER);
default_frag_shader.Compile();

//program
Memento::GLProgram default_program;
default_program.Create();
default_program.AttachShader(default_vert_shader);
default_program.AttachShader(default_frag_shader);

Memento::GLVertexArray default_vert_array;
default_vert_array.Create();
default_vert_array.Bind();

//BufferGameMap class- where I believe the issue lies
Memento::TextureAtlas atlas1("atlas/cat_image.png", "atlas/cat_source.xml");
Memento::BufferGameMap map1("tryagain.tmx", atlas1);

//bind buffers
map1.GetVertexBuffer().Bind();
map1.GetIndexBuffer().Bind();

//upload vertex attributes
default_vert_array.EnableIndex(0);
default_vert_array.IndexData(0, 2, GL_FLOAT, NULL, 8 * sizeof(Memento::M_float));
default_vert_array.BindIndex(default_program, 0, "map_vert");

//link, validate, and use program
default_program.Link();
default_program.Validate();
default_program.Use();

//upload matrix as uniform
glUniformMatrix4fv(default_program.GetUniformLocation("modelviewprojection_matrix"),
        1, GL_FALSE, ortho_matrix);

//main draw loop
while(not glfwGetKey(GLFW_KEY_ESC)){
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glDrawElements(GL_TRIANGLES, map1.GetIndexBufferLength(), GL_UNSIGNED_INT, NULL);
    glfwSwapBuffers();
}

//close window & exit
main_window.Close();

return (0);

}

BufferGameMap クラス (問題はおそらくここにあります!):

Memento::BufferGameMap::BufferGameMap(std::string const& file, const Memento::TextureAtlas& atlas):
    TmxMap::GameMap(), background_color_color4(), vertex_buffer(), index_buffer(),
    vertex_buffer_len(0), index_buffer_len(0){

    Create(file, atlas);
}

Memento::M_void Memento::BufferGameMap::Create(std::string const& file, const       Memento::TextureAtlas& atlas){

if(IsCreated())Destroy();
TmxMap::GameMap::CreateFromFile(file);

std::vector<TmxMap::Layer> const& layers = GetLayers();

if(not layers.empty()){
    const std::vector<TmxMap::Layer>::const_iterator layers_end = layers.end();
    std::vector<TmxMap::Layer>::const_iterator layers_iter = layers.begin();

    Memento::M_float* vertex_buffer_data = NULL;
    Memento::M_uint* index_buffer_data = NULL;

    for(; layers_iter != layers_end; ++layers_iter){
        vertex_buffer_len += layers_iter -> GetMapTiles().size() * (4 * (2 +
                2 + 2 + 2));
        index_buffer_len += layers_iter -> GetMapTiles().size() * 6;
    }

    vertex_buffer_data = new Memento::M_float[vertex_buffer_len];
    index_buffer_data = new Memento::M_uint[index_buffer_len];

    //fill data to send to the gl
    Memento::M_sizei vertex_buffer_iter = 0, index_buffer_iter = 0, index_buffer_quad_iter = 0;

    //map data
    const Memento::M_uint map_size_x = GetMapSize().x, map_size_y = GetMapSize().y;
    const Memento::M_float map_tile_size_x = GetTileSize().x, map_tile_size_y = GetTileSize().y;

    //per layer data
    std::vector<TmxMap::MapTile> const* map_tiles = NULL;
    std::vector<TmxMap::MapTile>::const_iterator map_tiles_iter, map_tiles_end;

    //per tile data
    Memento::M_float map_origin_x = 0.0f, map_origin_y = 0.0f;

    for(layers_iter = layers.begin(); layers_iter != layers_end; ++layers_iter){

        map_tiles = &layers_iter -> GetMapTiles();
        for(map_tiles_iter = map_tiles -> begin(), map_tiles_end = map_tiles -> end();
                map_tiles_iter != map_tiles_end; ++map_tiles_iter,
                vertex_buffer_iter += 4 * (2 + 2 + 2 +
                        2), index_buffer_iter += 6,
                        index_buffer_quad_iter += 4){

            map_origin_x = static_cast<Memento::M_float>(map_tiles_iter -> map_tile_index /
                    map_size_y) * map_tile_size_x;
            map_origin_y = static_cast<Memento::M_float>(map_tiles_iter -> map_tile_index %
                    map_size_y) * map_tile_size_y;

            vertex_buffer_data[vertex_buffer_iter] = map_origin_x;
            vertex_buffer_data[vertex_buffer_iter + 1] = map_origin_y;
            //=========================================================
            vertex_buffer_data[vertex_buffer_iter + 8] = map_origin_x;
            vertex_buffer_data[vertex_buffer_iter + 9] = map_origin_y + map_tile_size_y;
            //=========================================================
            vertex_buffer_data[vertex_buffer_iter + 16] = map_origin_x + map_tile_size_x;
            vertex_buffer_data[vertex_buffer_iter + 17] = map_origin_y + map_tile_size_y;
            //=========================================================
            vertex_buffer_data[vertex_buffer_iter + 24] = map_origin_x + map_tile_size_x;
            vertex_buffer_data[vertex_buffer_iter + 25] = map_origin_y;
            //=========================================================

            index_buffer_data[index_buffer_iter] = index_buffer_quad_iter;
            index_buffer_data[index_buffer_iter + 1] = index_buffer_quad_iter + 1;
            index_buffer_data[index_buffer_iter + 2] = index_buffer_quad_iter + 2;
            index_buffer_data[index_buffer_iter + 3] = index_buffer_quad_iter;
            index_buffer_data[index_buffer_iter + 4] = index_buffer_quad_iter + 2;
            index_buffer_data[index_buffer_iter + 5] = index_buffer_quad_iter + 3;
        }

    }

    vertex_buffer.Create(GL_ARRAY_BUFFER, GL_STATIC_DRAW);
    vertex_buffer.Bind();
    vertex_buffer.AllocateRef(vertex_buffer_len * sizeof(Memento::M_float),
            static_cast<const Memento::M_void*>(vertex_buffer_data));
    vertex_buffer.Unbind();

    index_buffer.Create(GL_ELEMENT_ARRAY_BUFFER, GL_STATIC_DRAW);
    index_buffer.Bind();
    index_buffer.AllocateRef(index_buffer_len * sizeof(Memento::M_uint),
            static_cast<const Memento::M_void*>(index_buffer_data));
    index_buffer.Unbind();

    delete[] vertex_buffer_data;
    delete[] index_buffer_data;
}

}

頂点シェーダー:

#version 140

precision highp float;

uniform mat4 modelviewprojection_matrix;

in vec2 map_vert;

void main(){
    gl_Position = modelviewprojection_matrix * vec4(map_vert, 0, 1);
}

フラグメント シェーダー:

#version 140

precision highp float;

out vec4 frag_color;

void main(){
    frag_color = vec4(0.4, 0.2, 0.6, 0.5);
}
4

1 に答える 1

0

スタックメモリが不足していると思います。

ヒープにデータを割り当てることで、スタックが 1MB に制限されている間、プロセスで利用可能なすべてのメモリを使用できます。

mainつまり、スコープ外のオブジェクト割り当てをスコープ内に移動しますglobal

Memento::TextureAtlas * atlas1;//("atlas/cat_image.png", "atlas/cat_source.xml");
Memento::BufferGameMap * map1;//("tryagain.tmx", atlas1);

int main(){

    atlas1 =    new Memento::TextureAtlas("atlas/cat_image.png", "atlas/cat_source.xml");
    map1 =      new Memento::BufferGameMap("tryagain.tmx", atlas1);

    //.... acess with ->

}

または、これがコンパイラ エラーを引き起こさない場合:

Memento::TextureAtlas atlas1("atlas/cat_image.png", "atlas/cat_source.xml");
Memento::BufferGameMap map1("tryagain.tmx", atlas1);

int main(){
    //.... acess with .

}
于 2013-06-11T09:33:51.167 に答える