glDrawArrays segmentation fault - c++

I am trying to render a simple triangle with OpenGL 3.3, but when I call glDrawArrays my program crashes with a segmentation fault. The language I'm using is C++ and I use the libraries SDL, glew and glm.
I think what happens is, that the draw call tries to access data that doesn't belong to the vertex buffer I have set up.
For reasons that don't really matter I can not provide the whole source code of my program. However I can provide some relevant snippets and a trace of the OpenGL calls issued, generated with the tool Apitrace.
[...]
glClearColor(red = 0, green = 0, blue = 0.5, alpha = 1)
glClear(mask = COLOR_BUFFER_BIT)
glGenVertexArrays(n = 1, arrays = &1)
glBindVertexArray(array = 1)
glGenBuffers(n = 1, buffer = &1)
glBindBuffer(target = GL_ARRAY_BUFFER, buffer = 1)
glBufferData(target = GL_ARRAY_BUFFER, size = 72, data = blob(72), usage = GL_STATIC_DRAW)
glVertexAttribPointer(index = 0, size = 3, type = GL_FLOAT, normalized = GL_FALSE, stride = 24, pointer = NULL)
glVertexAttribPointer(index = 1, size = 3, type = GL_FLOAT, normalized = GL_FALSE, stride = 24, pointer = 0xc)
glEnableVertexAttribArray(index = 0)
glEnableVertexAttribArray(index = 1)
glCreateShader(type = GL_VERTEX_SHADER) = 1
glShaderSource(shader = 1, count = 1, string = &"#version 330
layout (location = 0) in vec3 iPosition;
layout (location = 1) in vec3 iNormal;
void main() {
gl_Position = vec4(iPosition.x, iPosition.y, iPosition.z, iNormal.z * -1.0);
}", length = NULL)
glCreateShader(type = GL_FRAGMENT_SHADER) = 2
glShaderSource(shader = 2, count = 1, string = &"#version 330
out vec4 oFragColor;
void main() {
oFragColor = vec4(1.0, 0.0, 0.0, 1.0);
}", length = NULL)
glCompileShader(shader = 1)
glGetShaderiv(shader = 1, pname = GL_COMPILE_STATUS, params = &1)
glCompileShader(shader = 2)
glGetShaderiv(shader = 2, pname = GL_COMPILE_STATUS, params = &1)
glCreateProgram() = 3
glAttachShader(program = 3, shader = 1)
glAttachShader(program = 3, shader = 2)
glBindAttribLocation(program = 3, index = 1, name = "iNormal")
glBindAttribLocation(program = 3, index = 0, name = "iPosition")
glLinkProgram(program = 3)
glGetProgramiv(program = 3, pname = GL_LINK_STATUS, params = &1)
glGetAttribLocation(program = 3, name = "iPosition") = 0
glGetAttribLocation(program = 3, name = "iNormal") = 1
glGetIntegerv(pname = GL_CURRENT_PROGRAM, params = &0)
glUseProgram(program = 3)
glBindVertexArray(array = 1)
glClear(mask = GL_COLOR_BUFFER_BIT)
glDrawArrays(mode = GL_TRIANGLES, first = 0, count = 3) //incomplete (segfault here)
As I said, I think the problem is, that the draw call tries to access data in a wrong way. I have already checked the data in the vertex buffer using glGetBufferSubData. So here is the Code i use to set up the VAO:
Mesh::Mesh(const std::vector<Triangle>& triangles): _vao(0), _vbo(0) {
glGenVertexArrays(1, &_vao);
glBindVertexArray(_vao);
glGenBuffers(1, &_vbo);
glBindBuffer(GL_ARRAY_BUFFER, _vbo);
struct Vertex {
glm::vec3 position;
glm::vec3 normal;
}
Vertex* vertecies = new Vertex[triangles.size() * 3];
// [...]
// Convert triangles to vertecies, store them in the array.
glBufferData(GL_ARRAY_BUFFER, triangles.size() * 3 * sizeof(Vertex), vertecies, GL_STATIC_DRAW);
delete[] vertecies;
//Position
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), reinterpret_cast<void*>(0));
//Normal
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), reinterpret_cast<void*>(3 * sizeof(GL_FLOAT)));
glEnableVertexAttribArray(0);
glEnableVertexAttribArray(1);
}
I suspect the error to be in the way I call glVertexAttribPointer.
If other parts of the program are necessary to answer, leave me a comment and I'll see what I can do to provide them.

I dont see anything wrong with your code. I usually get this problem when my context isnt set correctly. For example, when I dont have GLEW set up correctly in my case. That may be the same problem for you.

Related

OpenGL Consuming ~50% GPU While Producing Nothing

Overview
We have an image/movie viewer powered via Qt5 and OpenGL that performs well however, we find that the draw surface itself consumes a large swath of resources no matter what is playing, even when we strip down the shaders.
We've added timing (gl query timers) for all of our own, custom, tools and cannot locate the source of the additional performance draw. The draw times are quite low considering our use case (~7ms per frame).
This is for an image rendering app; So 2D textures only. We use 2 triangles to cover the viewport and then dynamically generate the fragment based on the input requirements. This is for the film industry in which we do many many things to an image in terms of color and composite.
Discovery
We've stripped down the fragment to near nothing:
#version 330 core
void main() {
outColor = vec4(0.5, 0.0, 0.0, 1.0);
}
We've also disabled all PBO usage and have no uniform assignment. All timers read 0-1024ns for all of their commands (because all of our own gl commands are disabled)
The draw surface only calls paintGL, the Qt paint event for their OpenGL widget, once every ~42ms (24fps). Even with the simplicity of this, we use 70-80% of a GTX 1050 (resolution 3000x2000)
While this card is by no means a powerhouse, we are expecting to see less usage than that for something as simple as a solid color fragment. If we shrink the OpenGL window down to nothing, to only render the additional UI elements, we see ~5% usage. So our OpenGL surface that's doing next to nothing at a fixed frame rate is still consuming ~60-70% of the GPU for a reason we cannot determine.
Misc Info:
https://forum.qt.io/topic/121179/high-gpu-usage-when-animating/2
Additional Testing
We've attempted an apitrace for the gl commands but nothing jumped out at us. This included turn off the blit from our render frame buffer to the windows' buffer. So realistically, all of these are internal Qt-driven OpenGL commands.
10008 glViewport(x = 0, y = 0, width = 3000, height = 1896)
10009 glClearColor(red = 0, green = 0, blue = 0, alpha = 1)
10010 glClear(mask = GL_COLOR_BUFFER_BIT)
10011 glBindVertexArray(array = 1)
10012 glUseProgram(program = 7)
10013 glBindBuffer(target = GL_ARRAY_BUFFER, buffer = 9)
10014 glVertexAttribPointer(index = 0, size = 3, type = GL_FLOAT, normalized = GL_TRUE, stride = 0, pointer = NULL)
10015 glEnableVertexAttribArray(index = 0)
10016 glBindBuffer(target = GL_ARRAY_BUFFER, buffer = 0)
10017 glBindBuffer(target = GL_ARRAY_BUFFER, buffer = 10)
10018 glVertexAttribPointer(index = 1, size = 2, type = GL_FLOAT, normalized = GL_TRUE, stride = 0, pointer = NULL)
10019 glEnableVertexAttribArray(index = 1)
10020 glBindBuffer(target = GL_ARRAY_BUFFER, buffer = 0)
10021 glBindTexture(target = GL_TEXTURE_2D, texture = 1)
10022 glBindBuffer(target = GL_ARRAY_BUFFER, buffer = 9)
10023 glVertexAttribPointer(index = 0, size = 3, type = GL_FLOAT, normalized = GL_TRUE, stride = 0, pointer = NULL)
10024 glEnableVertexAttribArray(index = 0)
10025 glBindBuffer(target = GL_ARRAY_BUFFER, buffer = 0)
10026 glUniformMatrix4fv(location = 4, count = 1, transpose = GL_FALSE, value = {1, 0, 0, 0, 0, 0.8016878, 0, 0, 0, 0, 1, 0, 0, 0.1476793, 0, 1})
10027 glBindBuffer(target = GL_ARRAY_BUFFER, buffer = 10)
10028 glVertexAttribPointer(index = 1, size = 2, type = GL_FLOAT, normalized = GL_TRUE, stride = 0, pointer = NULL)
10029 glEnableVertexAttribArray(index = 1)
10030 glBindBuffer(target = GL_ARRAY_BUFFER, buffer = 0)
10031 glUniform1i(location = 1, v0 = 0)
10032 glUniformMatrix3fv(location = 3, count = 1, transpose = GL_FALSE, value = {1, 0, 0, 0, 1, 0, 0, 0, 1})
10033 glDrawArrays(mode = GL_TRIANGLES, first = 0, count = 6)
10034 glBindTexture(target = GL_TEXTURE_2D, texture = 0)
10035 glPixelStorei(pname = GL_UNPACK_ROW_LENGTH, param = 3000)
10036 glBindTexture(target = GL_TEXTURE_2D, texture = 2)
10037 glTexSubImage2D(target = GL_TEXTURE_2D, level = 0, xoffset = 0, yoffset = 48, width = 3000, height = 1520, format = GL_RGBA, type = GL_UNSIGNED_BYTE, pixels = blob(18240000))
10038 glPixelStorei(pname = GL_UNPACK_ROW_LENGTH, param = 0)
10039 glEnable(cap = GL_BLEND)
10040 glBlendFuncSeparate(sfactorRGB = GL_ONE, dfactorRGB = GL_ONE_MINUS_SRC_ALPHA, sfactorAlpha = GL_ONE, dfactorAlpha = GL_ONE)
10041 glBindTexture(target = GL_TEXTURE_2D, texture = 2)
10042 glBindBuffer(target = GL_ARRAY_BUFFER, buffer = 9)
10043 glVertexAttribPointer(index = 0, size = 3, type = GL_FLOAT, normalized = GL_TRUE, stride = 0, pointer = NULL)
10044 glEnableVertexAttribArray(index = 0)
10045 glBindBuffer(target = GL_ARRAY_BUFFER, buffer = 0)
10046 glUniformMatrix4fv(location = 4, count = 1, transpose = GL_FALSE, value = {1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1})
10047 glBindBuffer(target = GL_ARRAY_BUFFER, buffer = 10)
10048 glVertexAttribPointer(index = 1, size = 2, type = GL_FLOAT, normalized = GL_TRUE, stride = 0, pointer = NULL)
10049 glEnableVertexAttribArray(index = 1)
10050 glBindBuffer(target = GL_ARRAY_BUFFER, buffer = 0)
10051 glUniform1i(location = 1, v0 = 1)
10052 glUniformMatrix3fv(location = 3, count = 1, transpose = GL_FALSE, value = {1, 0, 0, 0, -1, 0, 0, 1, 1})
10053 glDrawArrays(mode = GL_TRIANGLES, first = 0, count = 6)
10054 glBindTexture(target = GL_TEXTURE_2D, texture = 0)
10055 glDisable(cap = GL_BLEND)
10056 glUseProgram(program = 0)
10057 glBindVertexArray(array = 0)
10058 wglSwapBuffers(hdc = 0xffffffff86011399) = TRUE
Any ideas would be excellent. I'm also happy to provide more information if required.

Why this projection gives a wrong result?

I try to obtain a so called world space coordinates for 2D rendering by creating a orthogonal projection matrix. But the result is disappointing I expect a blue triangle but there is only some blue pixels in the bottom right.
Here is my code in Nim language. It's a very simplified version who reproduces the issue.
The important part is in the function "projection2D", or maybe in the vertex shader. I don't think the problem is elsewhere but for safety I post the complete example
type
OGLfloat = float32
OGLuint = uint32
OGLint = int32
type Mat4x4* = array[16, OGLfloat] # 4 x 4 Matrix
# Here OpenGL constants should be here but not pasted to save space.
#....
const
POSITION_LENGTH = 3.OGLint
COLOR_LENGTH = 4.OGLint
const
WINDOW_W = 640
WINDOW_H = 480
let
colorDataOffset = POSITION_LENGTH * OGLint(sizeof(OGLfloat))
# OpenGL function import should be here.
#...
var
# Thanks to an orthogonal projection matrix I expect to use coordinates in pixels.
vertices = #[OGLfloat(420), 0, 0, # Position
0, 0, 1, 1, # Color
640, 480, 0,
0, 0, 1, 1,
0, 480, 0,
0, 0, 1, 1]
indices = #[OGLuint(0), 1 , 2]
proc projection2D(left, right, bottom, top, far, near:float):Mat4x4 =
result = [OGLfloat(1), 0, 0, 0, # Start from an identity matrix.
0, 1, 0, 0,
0, 0, 1, 0,
0, 0, 0, 1]
# Orthographic projection, inspired from a Wikipedia article example.
result[0] = OGLfloat(2.0 / (right - left))
result[5] = OGLfloat(2.0 / (top - bottom))
result[3] = OGLfloat(- ((right + left) / (right - left)))
result[7] = OGLfloat(- ((top + bottom) / (top - bottom)))
result[10] = OGLfloat(-2 / (far - near))
result[11] = OGLfloat(-((far + near)/(far - near)))
# These parameters comes from "learnopengl.com".
var projectionMatrix = projection2D(0.0, OGLfloat(WINDOW_W), OGLfloat(WINDOW_H), 0.0, - 1.0, 1.0)
var glfwErr = glfwInit()
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3)
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3)
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE)
var winHandle = glfwCreateWindow(WINDOW_W, WINDOW_H)
glfwMakeContextCurrent(winHandle)
var glewErr = glewInit()
var
shadID:OGLuint
vertSrc:cstring = """
#version 330 core
layout (location = 0) in vec3 aPos;
layout (location = 1) in vec4 aColor;
out vec4 vColor;
uniform mat4 projection;
void main()
{
gl_Position = projection * vec4(aPos, 1.0f);
vColor = aColor;
}
"""
fragSrc:cstring = """
#version 330 core
out vec4 FragColor;
in vec4 vColor;
void main()
{
FragColor = vColor;
}
"""
proc send_src(vert:var cstring, frag:var cstring):OGLuint =
var success:OGLint
# vertex
var vertexShader = glCreateShader(GL_VERTEX_SHADER)
glShaderSource(vertexShader, 1, addr vert, nil)
glCompileShader(vertexShader)
# Check compilation errors.
glGetShaderiv(vertexShader, GL_COMPILE_STATUS, addr success)
if bool(success) == false:
echo(" vertex shader compilation failed (send_src)")
else:
echo("vertexShader compiled (send_src)")
# fragment
var fragmentShader = glCreateShader(GL_FRAGMENT_SHADER)
glShaderSource(fragmentShader, 1, addr frag, nil)
glCompileShader(fragmentShader)
# Check compilation errors.
glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, addr success)
if bool(success) == false:
echo("fragment shader compilation failed (send_src)")
else:
echo("fragmentShader compiled (send_src)")
# Shader program
result = glCreateProgram()
glAttachShader(result, vertexShader)
glAttachShader(result, fragmentShader)
glLinkProgram(result)
# Check for linkage errors.
glGetProgramiv(result, GL_LINK_STATUS, addr success)
if success == 0:
echo("program linking failed (send_src)")
else:
echo("shader linked (send_src)")
glDeleteShader(vertexShader)
glDeleteShader(fragmentShader)
glViewport(0, 0, WINDOW_W, WINDOW_H)
shadID = send_src(vertSrc, fragSrc)
var VAO, VBO, EBO:OGLuint
glGenVertexArrays(1, addr VAO)
glGenBuffers(1, addr VBO)
glGenBuffers(1, addr EBO)
glBindVertexArray(VAO)
glBindBuffer(GL_ARRAY_BUFFER, VBO)
glBufferData(GL_ARRAY_BUFFER, vertices.len * sizeof(OGLfloat),
addr vertices[0], GL_STATIC_DRAW)
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO)
glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.len * sizeof(OGLuint),
addr indices[0], GL_STATIC_DRAW)
# Position layout
glVertexAttribPointer(0, POSITION_LENGTH, GL_FLOAT, GL_FALSE, (POSITION_LENGTH + COLOR_LENGTH) * OGLint(sizeof(OGLfloat)),
nil)
glEnableVertexAttribArray(0)
# Color layout
glVertexAttribPointer(1, COLOR_LENGTH, GL_FLOAT, GL_FALSE, (POSITION_LENGTH + COLOR_LENGTH) * OGLint(sizeof(OGLfloat)),
cast[pointer](colorDataOffset))
glEnableVertexAttribArray(1)
glBindBuffer(GL_ARRAY_BUFFER, 0)
glBindVertexArray(0)
glUseProgram(shadID)
while bool(glfwWindowShouldClose(winHandle)) == false:
glClearColor(0.2, 0.3, 0.3, 1.0)
glClear(GL_COLOR_BUFFER_BIT)
glBindVertexArray(VAO)
glUniformMatrix4fv(glGetUniformLocation(shadID, "projection"), 1, GL_FALSE, addr projectionMatrix[0])
glDrawElements(GL_TRIANGLES, OGLint(indices.len), GL_UNSIGNED_INT, nil)
glfwSwapBuffers(winHandle)
glfwPollEvents()
glDeleteVertexArrays(1, addr VAO)
glDeleteBuffers(1, addr VBO)
glDeleteBuffers(1, addr EBO)
glfwDestroyWindow(winHandle)
glfwTerminate()
Don't hesitate to share your thoughts !
You have to transpose the projection matrix, this means the 3rd parameter of glUniformMatrix4fv has to be GL_TRUE:
glUniformMatrix4fv(glGetUniformLocation(shadID, "projection"),
1, GL_TRUE, addr projectionMatrix[0])
Or you have to initialize the matrix according to the specification (see below):
proc projection2D(left, right, bottom, top, far, near:float):Mat4x4 =
result = [OGLfloat(1), 0, 0, 0, # Start from an identity matrix.
0, 1, 0, 0,
0, 0, 1, 0,
0, 0, 0, 1]
# Orthographic projection, inspired from a Wikipedia article example.
result[0] = OGLfloat(2.0 / (right - left))
result[5] = OGLfloat(2.0 / (top - bottom))
result[12] = OGLfloat(- ((right + left) / (right - left)))
result[13] = OGLfloat(- ((top + bottom) / (top - bottom)))
result[10] = OGLfloat(-2 / (far - near))
result[14] = OGLfloat(-((far + near)/(far - near)))
See The OpenGL Shading Language 4.6, 5.4.2 Vector and Matrix Constructors, page 101:
To initialize a matrix by specifying vectors or scalars, the components are assigned to the matrix elements in column-major order.
mat4(float, float, float, float, // first column
float, float, float, float, // second column
float, float, float, float, // third column
float, float, float, float); // fourth column
Note, in compare to a mathematical matrix where the columns are written from top to bottom, which feels natural, at the initialization of an OpenGL matrix, the columns are written from the left to the right. This leads to the benefit, that the x, y, z components of an axis or of the translation are in direct succession in the memory.
See also Data Type (GLSL) - Matrix constructors

ssbo in my particles system is not updated

I work on particles system and I want to use SSBO to make update of velocity and position on my particles with compute shader. But I see for each update-call the compute use same values of positions but compute update position because in draw-call particles are moved.
Load particles into SSBOs
// Load Positions
glGenBuffers(1, &m_SSBOpos);
glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_SSBOpos);
// Allocation de la mémoire vidéo
glBufferData(GL_SHADER_STORAGE_BUFFER, pb.size() * 4 * sizeof(float), NULL, GL_STATIC_DRAW);
GLint bufMask = GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT; // the invalidate makes a big difference when re-writing
float *points = (float *) glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, pb.size() * 4 * sizeof(float), bufMask);
for (int i = 0; i < pb.size(); i++)
{
points[i * 4] = pb.at(i).m_Position.x;
points[i * 4 + 1] = pb.at(i).m_Position.y;
points[i * 4 + 2] = pb.at(i).m_Position.z;
points[i * 4 + 3] = 0;
}
glUnmapBuffer(GL_SHADER_STORAGE_BUFFER);
// Load vélocité
glGenBuffers(1, &m_SSBOvel);
glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_SSBOvel);
// Allocation de la mémoire vidéo
glBufferData(GL_SHADER_STORAGE_BUFFER, pb.size() * 4 * sizeof(float), NULL, GL_STATIC_DRAW);
float *vels = (float *)glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, pb.size() * 4 * sizeof(float), bufMask);
for (int i = 0; i < pb.size(); i++)
{
vels[i * 4] = pb.at(i).m_Velocity.x;
vels[i * 4 + 1] = pb.at(i).m_Velocity.y;
vels[i * 4 + 2] = pb.at(i).m_Velocity.z;
vels[i * 4 + 3] = 0;
}
glUnmapBuffer(GL_SHADER_STORAGE_BUFFER);
Update
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 4, shaderUtil.getSSBOpos());
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 5, shaderUtil.getSSBOvel());
// UPDATE DES PARTICULES
shaderUtil.UseCompute();
glUniform1i(shaderUtil.getDT(), fDeltaTime);
glDispatchCompute(NUM_PARTICLES / WORK_GROUP_SIZE, 1, 1);
glMemoryBarrier(GL_SHADER_STORAGE_BARRIER_BIT);
shaderUtil.DeleteCompute();
Draw
shaderUtil.Use();
glUniformMatrix4fv(glGetUniformLocation(shaderUtil.getProgramID(), "projection"), 1, GL_FALSE, glm::value_ptr(projection));
glUniformMatrix4fv(glGetUniformLocation(shaderUtil.getProgramID(), "modelview"), 1, GL_FALSE, glm::value_ptr(View * Model));
glPointSize(10);
// Rendu
glBindBuffer(GL_ARRAY_BUFFER, shaderUtil.getSSBOpos());
glVertexPointer(4, GL_FLOAT, 0, (void *)0);
glEnableClientState(GL_VERTEX_ARRAY);
glDrawArrays(GL_POINTS, 0, NUM_PARTICLES);
glDisableClientState(GL_VERTEX_ARRAY);
glBindBuffer(GL_ARRAY_BUFFER, 0);
shaderUtil.Delete();
Comput shader
#version 430 compatibility
#extension GL_ARB_compute_shader : enable
#extension GL_ARB_shader_storage_buffer_object : enable
layout(std140, binding = 4) buffer Pos
{
vec4 Positions[]; // array of structures
};
layout(std140, binding = 5) buffer Vel
{
vec4 Velocities[]; // array of structures
};
uniform float dt;
layout(local_size_x = 128, local_size_y = 1, local_size_z = 1) in;
void main()
{
uint numParticule = gl_GlobalInvocationID.x;
vec4 v = Velocities[numParticule];
vec4 p = Positions[numParticule];
vec4 tmp = vec4(0, -9.81, 0,0) + v * (0.001 / (7. / 1000.));
v += tmp ;
Velocities[numParticule] = v;
p += v ;
Positions[numParticule] = p;
}
Do you know why it's happened ?

glGetBufferSubData returns the same data between two iterations of glDrawTransformFeedback()

I try to build a OpenGL program that do the Newton-Raphson method for five values at the same time. Actually, I just want to learn how to use TRANSFORM FEEDBACK
The vertex Shader just passes the value to geometry Shader
const GLchar* vertexShaderSrc = R"glsl(
#version 330 core
layout (location = 0) in float result;
layout (location = 1) in float val;
layout (location = 2) in float iterTime;
layout (location = 3) in float type;
out float geoResult;
out float geoVal;
out float geoIterTime;
out float geoType;
void main()
{
geoResult = result;
geoVal = val;
geoIterTime = iterTime;
geoType = type;
})glsl";
The Geometry Shader creates five new value to buffer and cached by transform feedback at the first time. Then, the program makes iteration for five values.
const GLchar* geometryShaderSrc = R"glsl(
#version 330 core
layout(points) in;
layout(points,max_vertices=100) out;
#define START_POINT 1.0f
#define REST_POINT 2.0f
in float geoResult[];
in float geoVal[];
in float geoIterTime[];
in float geoType[];
out float outResult;
out float outVal;
out float outIterTime;
out float outType;
void main(){
if(geoType[0] == START_POINT){
for(int i = 1; i<=5; ++i){
outResult = geoVal[0]/2;
outVal = geoVal[0]+50*i;
outIterTime = geoIterTime[0];
outType = REST_POINT;
EmitVertex();
}
EndPrimitive();
}
else{
outResult = geoResult[0]/2 + geoVal[0] / geoResult[0]/2;
outVal = geoVal[0];
outIterTime = geoIterTime[0] - 1;
outType = REST_POINT;
EmitVertex();
EndPrimitive();
}
} )glsl";
The loop is as follow
while (iterTimeCount-->0)
{
glEnable(GL_RASTERIZER_DISCARD);
// specify VBO and TFO
glBindBuffer(GL_ARRAY_BUFFER, nodeBuffer[currVB]);
glBindTransformFeedback(GL_TRANSFORM_FEEDBACK, transformFeedback[currTFB]);
glEnableVertexAttribArray(0);
glEnableVertexAttribArray(1);
glEnableVertexAttribArray(2);
glEnableVertexAttribArray(3);
glVertexAttribPointer(0, 1, GL_FLOAT, GL_FALSE, sizeof(resolveNode), (const GLvoid*) 0); // result
glVertexAttribPointer(1, 1, GL_FLOAT, GL_FALSE, sizeof(resolveNode), (const GLvoid*) 4); // val
glVertexAttribPointer(2, 1, GL_FLOAT, GL_FALSE, sizeof(resolveNode), (const GLvoid*) 8); // iterTime
glVertexAttribPointer(3, 1, GL_FLOAT, GL_FALSE, sizeof(resolveNode), (const GLvoid*) 12); // type
glBeginTransformFeedback(GL_POINTS);
// specially do drawing for the first particle. the rest of the particles will be
// create and drawn by TransformFeedback
if (isFirst) {
glDrawArrays(GL_POINTS, 0, 1);
isFirst = false;
}
else {
glDrawTransformFeedback(GL_POINTS, transformFeedback[currVB]);
}
glEndTransformFeedback();
glDisableVertexAttribArray(0);
glDisableVertexAttribArray(1);
glDisableVertexAttribArray(2);
glDisableVertexAttribArray(3);
glGetBufferSubData(GL_TRANSFORM_FEEDBACK_BUFFER,
0, sizeof(feedback), feedback);
for(int i = 0; i < 5; ++i){
printf("%f\t%f\t%f\t| ",feedback[i].result,feedback[i].val,feedback[i].iterTime);
}
printf("\n\n");
// switch VBO and TBO
currVB = currTFB;
currTFB = (currTFB + 1) & 0x1;
}
focus on feedback[i].iterTime , I get 10 10 8 8 6 6 4 4 2 2 0 , which should be 10 9 8 7 6 5 4 3 2 1 0. Amazing...

OS X OpenGL 3.2 Core (Black Screen)

I want to render a Quad via VAO, IBO and VBO but nothing is drawn. I'm using glDrawRangeElements in OS X OpenGL 3.2 Core context. The screen is completely black without any error. GLFW3 is used to create window and context.
Window opening/Context creation code
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 2);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
_mainWindow = glfwCreateWindow(width, height, title, monitor, NULL);
if(_mainWindow == NULL)
{
return false;
}
_mainWindowWidth = width;
_mainWindowHeight = height;
glfwSetKeyCallback(_mainWindow, _onKeyEvent);
glfwMakeContextCurrent(_mainWindow);
glewExperimental = GL_TRUE;
glewInit();
_openGLVersion = reinterpret_cast<const char*>(glGetString(GL_VERSION));
Shader sources (compiled successfully). Custom FragColor is binded.
_vertexShaderSource =
"#version 150 core\n"
"in vec3 in_Position;\n"
"in vec3 in_Normal;\n"
"in vec2 in_TexCoord;\n"
"uniform mat4 ModelViewProjection;\n"
"void main()\n"
"{\n"
" gl_Position = ModelViewProjection * vec4(in_Position, 1.0);\n"
"}\n";
_fragmentShaderSource =
"#version 150 core\n"
"out vec4 FColor;"
"void main()\n"
"{\n"
" FColor = vec4(1.0, 1.0, 1.0, 1.0);\n"
"}\n";
Vertices
Vertex* vertices = new Vertex[6];
vertices[0].nz = 1.0f;
vertices[1].nz = 1.0f;
vertices[2].nz = 1.0f;
vertices[3].nz = 1.0f;
vertices[4].nz = 1.0f;
vertices[5].nz = 1.0f;
vertices[1].y = height;
vertices[1].v0 = 1.0f;
vertices[2].x = width;
vertices[2].y = height;
vertices[2].u0 = 1.0f;
vertices[2].v0 = 1.0f;
vertices[4].x = width;
vertices[4].u0 = 1.0f;
vertices[5].x = width;
vertices[5].y = height;
vertices[5].u0 = 1.0f;
vertices[5].v0 = 1.0f;
_mesh->setVertices(vertices, 6);
vertices = NULL;
Uint16* indices = new Uint16[6];
indices[0] = 0;
indices[1] = 2;
indices[2] = 3;
indices[3] = 0;
indices[4] = 1;
indices[5] = 3;
_mesh->setIndices(indices);
indices = NULL;
Buffer update (checked the data, it seems to be correct)
// Update VBO
if(_vertexBufferObjectID == 0)
{
glGenBuffers(1, &_vertexBufferObjectID);
}
glBindBuffer(GL_ARRAY_BUFFER, _vertexBufferObjectID);
float* data = new float[_vertexCount * sizeof(Vertex) / sizeof(float)];
Uint64 begin = 0;
for(Uint32 i = 0; i < _vertexCount; i++)
{
begin = i * 8;
data[begin] = _vertices[i].x;
data[begin + 1] = _vertices[i].y;
data[begin + 2] = _vertices[i].z;
data[begin + 3] = _vertices[i].nx;
data[begin + 4] = _vertices[i].ny;
data[begin + 5] = _vertices[i].nz;
data[begin + 6] = _vertices[i].u0;
data[begin + 7] = _vertices[i].v0;
}
glBufferData(GL_ARRAY_BUFFER, sizeof(Vertex) * _vertexCount, &data[0], GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0);
delete[] data;
data = NULL;
// Update IBO
if(_indexBufferObjectID == 0)
{
glGenBuffers(1, &_indexBufferObjectID);
}
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _indexBufferObjectID);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(Uint16) * _vertexCount, &_indices[0], GL_STATIC_DRAW);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
// Update VAO
if(_vertexArrayObjectID == 0)
{
glGenVertexArrays(1, &_vertexArrayObjectID);
}
glBindVertexArray(_vertexArrayObjectID);
glBindBuffer(GL_ARRAY_BUFFER, _vertexBufferObjectID);
// Vertices
glEnableVertexAttribArray(0);
glEnableVertexAttribArray(1);
glEnableVertexAttribArray(2);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), ((char*)NULL + (0)));
// Normals
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), ((char*)NULL + (12)));
// TexCoords
glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), ((char*)NULL + (24)));
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _indexBufferObjectID);
glBindVertexArray(0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
Rendering code
glUseProgram(material->_programID);
GLuint mvp = glGetUniformLocation(material->_programID, "ModelViewProjection");
glUniformMatrix4fv(mvp, 1, false, glm::value_ptr(camera_mvp));
glBindVertexArray(node->_mesh->_vertexArrayObjectID);
// Draw
glDrawRangeElements(GL_TRIANGLES, 0, 3, node->_mesh->_vertexCount, GL_UNSIGNED_SHORT, NULL);
glBindVertexArray(0);
Note:
camera_mvp is Orthographic
0.00333333_0___________0 0
0__________0.00333333__0 0
0__________0__________-1 0
599________599_________0 1
Program Linking
_programID = glCreateProgram();
glAttachShader(_programID, vertex_shader);
glAttachShader(_programID, fragment_shader);
glLinkProgram(_programID);
glGetProgramiv(_programID, GL_LINK_STATUS, &result);
glGetProgramiv(_programID, GL_INFO_LOG_LENGTH, &loglen);
if(loglen > 0)
{
char* log = new char[loglen];
glGetProgramInfoLog(_programID, loglen, 0, log);
_lastInfoLog = log;
delete log;
log = NULL;
}
if(result == GL_FALSE)
{
glDeleteProgram(_programID);
glDeleteShader(vertex_shader);
glDeleteShader(fragment_shader);
return false;
}
glUseProgram(_programID);
glBindAttribLocation(_programID, 0, "in_Position");
glBindAttribLocation(_programID, 1, "in_Normal");
glBindAttribLocation(_programID, 2, "in_TexCoord");
glBindFragDataLocation(_programID, 0, "FColor");
glUseProgram(0);
glDeleteShader(vertex_shader);
glDeleteShader(fragment_shader);
You don't have layout in #version 150 so you have to use glGetAttribLocation() to ask OpenGL where it put your attributes and adjust the first parameter of your glVertexAttribPointer() calls appropriately.
Make sure you bind your program before calling glGetAttribLocation().