0
\$\begingroup\$

I want to draw a selected number of instances using glDrawElements... but I don't know which function to use and how to set the parameters.

I set the gl_InstanceID in shader and set the shader data through SSBO:

glGenBuffers(1, &SSBO); glBindBuffer(GL_SHADER_STORAGE_BUFFER, SSBO); glBufferData(GL_SHADER_STORAGE_BUFFER, data_vector.size() * sizeof(data_type), data_vector.data(), GL_DYNAMIC_DRAW); glBindBufferBase(GL_SHADER_STORAGE_BUFFER, binding_index, SSBO); 

I have an array drawable_vector contains bool to check if the vertex is drawn or not.

for(auto index = 0; index < drawable_vector.size(); index ++){ glDrawElements...(???) } 

I want to draw instance with ID gl_instanceID only when the drawable_vector[index] is true. The size of drawable_vector, data_vector and number of instances are the same.

Edit: Setup & render code

Setup:

//VAO glGenVertexArrays(1, &VAO); glBindVertexArray(VAO); //VBO1 - Position glGenBuffers(1, &VBO1); glBindBuffer(GL_ARRAY_BUFFER, VBO1); glBufferData(GL_ARRAY_BUFFER, 3*sizeof(glm::vec4), vertices.data(), GL_DYNAMIC_DRAW); //VBO2 - color glGenBuffers(1, &VBO2); glBindBuffer(GL_ARRAY_BUFFER, VBO2); glBufferData(GL_ARRAY_BUFFER, 3*sizeof(glm::vec4), colors.data(), GL_DYNAMIC_DRAW); //EBO glGenBuffers(1, &EBO); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO); glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_DYNAMIC_DRAW); //SSBO - models in shader glGenBuffers(1, &SSBO); glBindBuffer(GL_SHADER_STORAGE_BUFFER, SSBO); glBufferData(GL_SHADER_STORAGE_BUFFER, models.size() * sizeof(glm::vec4), models.data(), GL_DYNAMIC_DRAW); glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 2, SSBO); //Set data of shader //in_pos glBindBuffer(GL_ARRAY_BUFFER, VBO1); glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, (void *) 0); glEnableVertexAttribArray(0); //in_color glBindBuffer(GL_ARRAY_BUFFER, VBO2); glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, 0, (void *) 0); glEnableVertexAttribArray(1); glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, 0); glMemoryBarrier(GL_SHADER_STORAGE_BARRIER_BIT); glBindVertexArray(0); 

Shader:

#version 450 core out vec4 frag_color; in vec4 out_color; void main() { frag_color = out_color; } 
#version 430 core layout (location = 0) in vec4 in_pos; layout (location = 1) in vec4 in_color; layout(std430, binding = 2) buffer DataBuffer { mat4 in_models[]; } buffer_data; uniform mat4 view; uniform mat4 projection; out vec4 out_color; void main() { out_color = in_color; gl_Position = projection * view * buffer_data.in_models[gl_InstanceID] * in_pos; } 

Render:

use_shader(); shader_set_view("view", view); shader_set_projection("projection", projection); update_models(); glBindVertexArray(VAO); glBindBuffer(GL_ARRAY_BUFFER, VBO1); glBindBuffer(GL_ARRAY_BUFFER, VBO2); glBindBuffer(GL_ARRAY_BUFFER, EBO); glBindBuffer(GL_SHADER_STORAGE_BUFFER, SSBO); glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 2, SSBO[0]); glDrawArraysInstanced(GL_TRIANGLES, 0, 3, n_instances); glfwSwapBuffers(window); glBindVertexArray(0); 
\$\endgroup\$

1 Answer 1

0
\$\begingroup\$

I figured it out.

Hav to use the command glDrawElementsInstancedBaseInstance and added gl_BaseInstance to the shader

void main() { out_color = in_color; gl_Position = projection * view * buffer_data.in_models[gl_BaseInstance+gl_InstanceID] * in_pos; } 

and set baseinstance in glDrawElementsInstancedBaseInstance to instance numbers to draw.

for(int r_index = 0; r_index < instance_id_list; r_index++) { glDrawElementsInstancedBaseInstance( GL_TRIANGLES, // type of primitive to render 3, // vertex count GL_UNSIGNED_INT, // type of each index in the GL_ELEMENT_ARRAY_BUFFER (void*)0, // element array buffer offset 1, // Number of copies to render instance_id_list[r_index] // Number to start from for InstanceId ); } 
\$\endgroup\$

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.