alestane icon

OpenGL test code

alestane | PRO | 02/23/16 06:58:41 PM UTC | 0 ⭐ | 523 👁️ | Never ⏰ | []
C++ |

5.02 KB

|

None

|

0 👍

/

0 👎

namespace shader {
    std::string vFlat =
    "#version 150" "\n"
 
    "uniform mat4 transform, camera, projection;" "\n"
 
    "in vec3 position, normal;" "\n"
    "in vec2 uv;" "\n"
 
    "out mat4 modelview;" "\n"
 
    "out vec3 frag_position, frag_normal;" "\n"
    "out vec2 frag_uv;" "\n"
 
    "void main() {" "\n"
        "modelview = camera * transform;" "\n"
        "vec4 eye_position = modelview * vec4(position, 1.0);" "\n"
        "gl_Position = projection * eye_position;" "\n"
        "frag_position = eye_position.xyz;" "\n"
        "frag_normal   = (modelview * vec4(normal, 0.0)).xyz;" "\n"
        "frag_uv = uv;" "\n"
    "}";
 
    std::string fFlat =
    "#version 150" "\n"
 
    "in mat4 modelview;" "\n"
 
    "in vec3 frag_position, frag_normal;" "\n"
    "in vec2 frag_uv;" "\n"
 
    "uniform vec4 color;" "\n"
 
    "const vec3 light_direction = vec3(0.408248, -0.816497, -0.408248);" "\n"
 
    "out vec4 fragColor;" "\n"
 
    "void main() {" "\n"
        "vec3 normal = normalize(frag_normal);" "\n"
 
        "float shade = 0.5 * (-dot(normal, normalize(light_direction)) + 1.0);" "\n"
        "fragColor = vec4(color.rgb * shade, color.a);" "\n"
    "}";
}
 
namespace gl {
    struct Vertex {
        glm::vec3 position;
        glm::vec3 normal;
        glm::vec2 uv;
    };
    
    class Object {
    public:
        glm::vec4 color;
        GLuint data;
        vector<GLushort> faces;
        GLuint program;
        mat4 transform;
    };
}
 
class OBJMesh {
public:
    OBJMesh(string const& filename);
    vector<gl::Vertex> verts;
    vector<GLushort> faces;
    vector<GLushort> segments;
}
 
gl::Object* cube = NULL;
 
void load() {  // assumes context is created : no errors up to this point
    GLuint v = glCreateShader(GL_VERTEX_SHADER), f = glCreateShader(GL_FRAGMENT_SHADER);
    GLint length = static_cast<GLint>(shader::vFlat.length());
    char const* text = shader::vFlat.c_str();
    glShaderSource(v, 1, &text, &length);
    glCompileShader(v);
    GLint status = GL_FALSE;
    glGetShaderiv(v, GL_COMPILE_STATUS, &status);
    length = static_cast<GLint>(shader::fFlat.length());
    text = shader::fFlat.c_str();
    glShaderSource(f, 1, &text, &length);
    glCompileShader(f);
    glGetShaderiv(f, GL_COMPILE_STATUS, &status);
    
    plain = glCreateProgram();
    glAttachShader(plain, v);
    glAttachShader(plain, f);
    glBindAttribLocation(plain, 0, "position");
    glBindAttribLocation(plain, 1, "normal");
    glBindAttribLocation(plain, 2, "uv");
    glLinkProgram(plain);
    glGetProgramiv(plain, GL_LINK_STATUS, &status);
    glDetachShader(plain, v);
    glDetachShader(plain, f);
    
    glUseProgram(plain);
    glUniformMatrix4fv(glGetUniformLocation(plain, "camera"), 1, GL_FALSE, glm::value_ptr(glm::lookAt(vec3(0.0f, 2.0f, 4.0f), vec3(0.0f, 0.0f, 0.0f), vec3(0.0f, 1.0f, 0.0f))));
    glUniformMatrix4fv(glGetUniformLocation(plain, "projection"), 1, GL_FALSE, glm::value_ptr(glm::frustum(-2.0f,  2.0f, -1.5f, 1.5f, 02.0f, -5.0f)));
    glUniformMatrix4fv(glGetUniformLocation(plain, "transform"), 1, GL_FALSE, glm::value_ptr(glm::mat4()));
    
    cube = new gl::Object();
    glGenVertexArrays(1, &cube->data);
    cube->program = plain;
    cube->color = glm::vec4(1.0f);
    cube->transform = glm::mat4();
    
    OBJMesh cubeMesh("cube.obj"); // confirmed working
    
    GLuint vbo, ebo;
    glGenBuffers(1, &vbo);
    glGenBuffers(1, &ebo);
    
    glBindBuffer(GL_ARRAY_BUFFER, vbo);
    glBufferData(GL_ARRAY_BUFFER, sizeof(gl::Vertex) * cubeMesh.verts.size(), cubeMesh.verts.data(), GL_STATIC_DRAW);
    glBindVertexArray(cube->data);
    glEnableVertexAttribArray(0);
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(gl::Vertex), reinterpret_cast<void*>(0));
    glEnableVertexAttribArray(1);
    glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(gl::Vertex), reinterpret_cast<void*>(sizeof(glm::vec3)));
    glEnableVertexAttribArray(2);
    glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, sizeof(gl::Vertex), reinterpret_cast<void*>(sizeof(glm::vec3)+sizeof(glm::vec3)));
    glBindVertexArray(0);
    glDisableVertexAttribArray(0);
    glDisableVertexAttribArray(1);
    glDisableVertexAttribArray(2);
    
    glBindVertexArray(cube->data); // because of C++ wrapper class in original code
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(GLushort) * cubeMesh.faces.size(), cubeMesh.faces.data(), GL_STATIC_DRAW);
    glBindVertexArray(0);
    
    glDeleteBuffers(1, &ebo);
    glDeleteBuffers(1, &vbo);
 
    cube->faces = cubeMesh.segments();
}
 
void render() {
    glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
    
    glUseProgram(cube->program);
    glUniform4fv(glGetUniformLocation(cube->program, "color"), 1, glm::value_ptr(cube->color));
    glUniformMatrix4fv(glGetUniformLocation(cube->program, "transform"), 1, GL_FALSE, glm::value_ptr(cube->transform));
    glBindVertexArray(cube->data);
    GLushort position = 0;
    for (GLushort range: faces) {
        // THIS glDrawElements LINE YIELDS GL_OUT_OF_MEMORY ON THE FIRST CALL!!!!!
        glDrawElements(GL_TRIANGLE_STRIP, range, GL_UNSIGNED_SHORT, reinterpret_cast<void*>(position * sizeof(GLushort)));
        position += range;
    }
    glBindVertexArray(0);
}

Comments