1

I'm working with openGL's Geometry Shader, and doing some tests to get the hang of it before I move on to more complex tasks. I wrote some code to transform inputted GL_POINTS into GL_TRIANGLE_STRIPs, and I apply the MVP matrix transformation in the Geometry Shader. While rendering without the MVP matrix produces the correct output, rendering with it produces nothing. Here is the code (hopefully minimal enough):

int main(){
// Create context and window
sf::Context context;
sf::Window window(sf::VideoMode(800, 600), "Voxel Engine");
window.setVerticalSyncEnabled(true);

// Initialize glew
glewExperimental = true;
GLenum err = glewInit();
if (err != GLEW_OK){
    std::cout << "glewIniti failed, aborting...\n";
}

// Create VAO
GLuint VertexArrayID;
glGenVertexArrays(1, &VertexArrayID);
glBindVertexArray(VertexArrayID);

glClearColor(0.0f, 0.0f, 0.4f, 0.0f);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LESS);

// Vector for verts
std::vector<glm::vec3> vertices;

// Insert a few vertices
for (int i = -5; i < 5; i++){
    vertices.push_back(glm::vec3(i*.3, 0.0, 0.0));
}

// View matrix vectors
glm::vec3 eye = glm::vec3(0.0f, 5.0f, 5.0f);
glm::vec3 at = glm::vec3(0.0f, 0.0f, 0.0f);
glm::vec3 up = glm::vec3(0.0f, 1.0f, 0.0f);

// Create VBO for vertices
GLuint vertexbuffer;
glGenBuffers(1, &vertexbuffer);
glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
glBufferData(GL_ARRAY_BUFFER, vertices.size()*sizeof(glm::vec3), &vertices[0], GL_STATIC_DRAW);

// Create MVP matrices
glm::mat4 Projection = glm::perspective(45.0f, 4.0f / 3.0f, 0.1f, 100.0f);
glm::mat4 View = glm::lookAt(eye, at, up);
glm::mat4 Model = glm::mat4(1.0f);

// Load the shaders
GLuint programID = LoadShaders("VertexShader.glsl", "GeometryShader.glsl", "FragmentShader.glsl");

// Get uniform locations
GLuint M = glGetUniformLocation(programID, "M");
GLuint V = glGetUniformLocation(programID, "V");
GLuint P = glGetUniformLocation(programID, "P");

// Main loop
bool running = true;
sf::Event event;
while (running){
    while (window.pollEvent(event)){
        switch (event.type){
        case sf::Event::Closed:
            window.close();
            return 0;
        }
    }
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glUseProgram(programID);

    glUniformMatrix4fv(M, 1, GL_FALSE, &Model[0][0]);
    glUniformMatrix4fv(V, 1, GL_FALSE, &View[0][0]);
    glUniformMatrix4fv(P, 1, GL_FALSE, &Projection[0][0]);

    glEnableVertexAttribArray(0);
    glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, (void*)0);

    glDrawArrays(GL_POINTS, 0, 10);

    glDisableVertexAttribArray(0);

    window.display();
}
return 0;
}

Vertex Shader:

#version 430 core
layout(location = 0) in vec3 position;
void main(){
gl_Position = vec4(position, 1);
}

Geometry Shader:

#version 430 core

layout (points) in;
uniform mat4 M, V, P;
layout (triangle_strip) out;
layout (max_vertices = 14) out;

void main(void){
// create a vertex for each point on the cube
vec4 v1 = M*V*P*(gl_in[0].gl_Position + vec4(.1, -.1, -.1, 0.0));
vec4 v2 = M*V*P*(gl_in[0].gl_Position + vec4(-.1, -.1, -.1, 0.0));
vec4 v3 = M*V*P*(gl_in[0].gl_Position + vec4(.1, .1, -.1, 0.0));
vec4 v4 = M*V*P*(gl_in[0].gl_Position + vec4(-.1, .1, -.1, 0.0));
vec4 v5 = M*V*P*(gl_in[0].gl_Position + vec4(.1, -.1, .1, 0.0));
vec4 v6 = M*V*P*(gl_in[0].gl_Position + vec4(-.1, -.1, .1, 0.0));
vec4 v7 = M*V*P*(gl_in[0].gl_Position + vec4(-.1, .1, .1, 0.0));
vec4 v8 = M*V*P*(gl_in[0].gl_Position + vec4(.1, .1, .1, 0.0));

gl_Position = v4;
EmitVertex();
gl_Position = v3;
EmitVertex();
gl_Position = v7;
EmitVertex();
gl_Position = v8;
EmitVertex();
gl_Position = v5;
EmitVertex();
gl_Position = v3;
EmitVertex();
gl_Position = v1;
EmitVertex();
gl_Position = v4;
EmitVertex();
gl_Position = v2;
EmitVertex();
gl_Position = v7;
EmitVertex();
gl_Position = v6;
EmitVertex();
gl_Position = v5;
EmitVertex();
gl_Position = v2;
EmitVertex();
gl_Position = v1;
EmitVertex();
EndPrimitive();
}

Fragment Shader:

#version 430 core

out vec4 color;

void main(){
color = vec4(0, 1, 0, 1);
}

I can provide my LoadShaders function if necessary, but I don't think the issue lies there.

So, performance aside, is there anything I'm doing which is blatantly incorrect?

Alex Coats
  • 115
  • 2
  • 16
  • Your vertex shader does something completely unnecessary, by the way. You can declare `layout(location = 0) in vec4 position;` instead and GL will automatically fill-in **1.0** for the w-component because your corresponding call to `glVertexAttribPointer(0, 3,` only supplies 3 of the 4 components. – Andon M. Coleman Feb 23 '15 at 17:23
  • 3
    As for your actual problem... are your matrices column-major? You appear to be multiplying the individual M, V and P matrices in the wrong order for GLSL. – Andon M. Coleman Feb 23 '15 at 17:25
  • I'm not sure. I'm using glm to deal with that and because it's build for openGL I assumed that it would work without transposing the matrices or anything. EDIT: So this was apparently the issue. I sent the matrices in transposed and it renders correctly now :D Thank you so much! – Alex Coats Feb 23 '15 at 18:49
  • 1
    GLM will output them in traditional column-major format. So that means your matrix multiplication in GLSL should be written this way: `P*V*M*(...)`. It seems counter-intuitive, but you should read that sequence of operations from right-to-left. You start out with something in object-space on the right and eventually transform it to clip-space on the left. _Transposing the matrices will do the same thing of course :P_ – Andon M. Coleman Feb 23 '15 at 18:53
  • Correction, transposing them did not work. Reversing the order, however, did. – Alex Coats Feb 23 '15 at 18:57
  • 1
    @AlexCoats: As a side note: You really should think about multiplying those matrices on the CPU and only send the combined result matrix to the shader. Doing this in the shader is just a waste of GPU's time. – derhass Feb 23 '15 at 20:35

0 Answers0