I’m sorry for the ambiguous title. I’m not really sure why this is happening, or even what is happening. But I’ll share some code and ideas about what the problem maybe about. So here’s what I was trying to do;
I’m trying to draw multiple lines seperated at certain intervals using a single mesh. Coordinates of the vertices get updated every frame using a pingpong framebuffer object to update the coordinate data stored in a texture. The problem is that when I use the shader program that updates the texture, the number of lines rendered decreases.
I’m trying to use geometry shader to draw simple lines to thick lines (which are actually rectangles drawn from GL_TRIANGLE_STRIP) using GLSL version 330. The process was intended to work like so;
- Set data for the coordinates as a vector, which in turn is put into a framebuffer object as GL_RGB32F texture.
- Set vertices for an ofVboMesh object.
- Update texture storing positions using a pingpong framebuffer object.
- Render GL_LINES_ADJACENCY mesh as GL_TRIANGLE_STRIP using geometry shader.
(code for 1~2 : setup) I was trying to draw tex_w * tex_h
number of shapes that are consisted of few lines that are connected to each other. I’m using GL_LINES_ADJACENCY primitive type, because I’m planning to use the adjacent vertex attributes in geometry shader. The reason I’m not using GL_LINE_STRIP_ADJACENCY is because I need the shape to be seperated at certain intervals. According to the code below, it should draw 16 shapes that are each consisted of 2 lines. (2 lines because GL_LINE_ADJACENCY uses 4 points to draw a single line) But It draws only 4 shapes.
glEnable(GL_DEPTH_TEST);
ofSetVerticalSync(false);
sh_p_render.setGeometryInputType(GL_LINES_ADJACENCY);
sh_p_render.setGeometryOutputType(GL_TRIANGLE_STRIP);
sh_p_render.setGeometryOutputCount(4);
sh_p_render.load("shaders/p_render.vert",
"shaders/p_render.frag",
"shaders/p_render.geom");
sh_p_pos.load("shaders/p_pos.vert","shaders/p_pos.frag");
tex_w = 4;
tex_h = 4;
c_num = 8;
vector<float> init_pos(tex_w * tex_h * c_num * 3);
particles_mesh.setMode(OF_PRIMITIVE_LINES_ADJACENCY);
float _x = 0;
float _y = 0;
for(int y = 0; y < tex_w; y++){
for(int x = 0; x < tex_h; x++){
for(int k = 0; k < c_num; k++){
int i = ( tex_h * y + x ) * c_num + k;
if(k == 0 || k % 4 == 2)
{
_x = ofRandom(1.0);
_y = ofRandom(1.0);
}
{
init_pos[i*3+0] = _x; //x
init_pos[i*3+1] = _y; //y
init_pos[i*3+2] = 0.0; //z
}
particles_mesh.addVertex({ x * c_num + k, y, 0 });
}
}
}
particles_p_PingPong.allocate(tex_w * c_num, tex_h, GL_RGB32F);
particles_p_PingPong.src->getTexture().loadData(init_pos.data(), tex_w * c_num, tex_h, GL_RGB);
particles_p_PingPong.dst->getTexture().loadData(init_pos.data(), tex_w * c_num, tex_h, GL_RGB);
fbo_render.allocate(ofGetWidth(), ofGetHeight(), GL_RGB32F);
fbo_render.begin();
ofClear(0,0,0,255);
fbo_render.end();
(Code for 3 : vertex shader)
#version 330
layout (location = 0) in vec4 position;
void main()
{
gl_Position = position;
}
(Code for 3 : fragment shader)
#version 330
out vec4 FragColor;
uniform sampler2DRect pos_texture;
void main()
{
vec2 tc = gl_FragCoord.xy - 0.5;
vec4 pos = texture(pos_texture,tc);
FragColor = pos;
}
(Code : update)
glm::mat4 projection;
glm::mat4 view = glm::mat4(1.0f);
glm::mat4 model = glm::mat4(1.0f);
float fov_angle = 45.0f;
float camera_distance = (2.0 * 0.5) / tan(glm::radians(fov_angle * 0.5));
projection = glm::perspective(glm::radians(fov_angle), (float)ofGetWidth() / (float)ofGetHeight(), 0.1f, 100.0f);
model = glm::rotate(model, glm::radians(0.0f), glm::vec3(1.0f, 0.0f, 0.0f));
view = glm::translate(view, glm::vec3(0.0f, 0.0f, -camera_distance));
particles_p_PingPong.dst->begin();
ofClear(0);
{
sh_p_pos.begin();
sh_p_pos.setUniformTexture("pos_texture", particles_p_PingPong.src->getTexture(), 1);
particles_p_PingPong.src->draw(0, 0);
sh_p_pos.end();
}
particles_p_PingPong.dst->end();
particles_p_PingPong.swap();
fbo_render.begin();
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
{
sh_p_render.begin();
sh_p_render.setUniformMatrix4f("projection", projection);
sh_p_render.setUniformMatrix4f("view", view);
sh_p_render.setUniformMatrix4f("model", model);
sh_p_render.setUniform1f("_LineWidth",0.05);
sh_p_render.setUniformTexture("pos_texture", particles_p_PingPong.src->getTexture(), 1);
sh_p_render.setUniform2f("res", (float)ofGetWidth(), (float)ofGetHeight());
particles_mesh.draw();
sh_p_render.end();
}
fbo_render.end();
(Code : draw)
ofBackground(0);
fbo_render.draw(0,0,ofGetWidth(),ofGetHeight());
ofSetColor(255);
ofDrawBitmapString("fps: " + ofToString((int)ofGetFrameRate()), 20, 20);
The wierd thing is when I comment out the code below from update, the program renders 16 shapes as intended. So I am guessing that the main problem is within the shader program.
particles_p_PingPong.dst->begin();
ofClear(0);
{
sh_p_pos.begin();
sh_p_pos.setUniformTexture("pos_texture", particles_p_PingPong.src->getTexture(), 1);
particles_p_PingPong.src->draw(0, 0);
sh_p_pos.end();
}
particles_p_PingPong.dst->end();
particles_p_PingPong.swap();
Another question I have is the part where I add the vertices to the mesh in setup.
for(int y = 0; y < tex_w; y++){
for(int x = 0; x < tex_h; x++){
for(int k = 0; k < c_num; k++){
int i = ( tex_h * y + x ) * c_num + k;
if(k == 0 || k % 4 == 2)
{
_x = ofRandom(1.0);
_y = ofRandom(1.0);
}
{
init_pos[i*3+0] = _x; //x
init_pos[i*3+1] = _y; //y
init_pos[i*3+2] = 0.0; //z
}
particles_mesh.addVertex({ x * c_num + k, y, 0 });
}
}
}
I thought that adding vertices to a mesh is simply adding coordinates to the object, so initially I thought that I should put the values of _x
and _y
, but when I did that, no lines rendered on screen. So I think I’m not fully understanding what addVertex() actually does.
I omitted the code for the shader program that uses geometry shader because that part seems to be working ok for the moment.
It would be nice if I could get some information about how to deal with this problem. Thank you.