Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #ifdef _WIN32
- #include <Windows.h>
- #endif
- #ifdef __APPLE__
- #include <OpenGL/gl.h>
- #include <Glut/glut.h>
- #else
- #include <GL/gl.h>
- #include <GL/glut.h>
- #endif
- #include <stdlib.h>
- #include <stdio.h>
- #include <math.h>
- #include "glm/glm.hpp"
- #include "glm/gtc/matrix_transform.hpp"
- #include "glm/gtc/type_ptr.hpp"
- //windowSize
- int windowWidth=640;
- int windowHeight=480;
- GLuint shaderProgram;
- GLint shaderAttribute_coord3D;
- GLint shaderAttribute_vertexColour;
- GLint shaderAttribute_uniform_mvp;
- GLint shaderAttribute_uniform_animation;
- //model vertices
- GLuint modelDataVBO;
- GLuint modelElements;
- char* readFile(const char* filename) {
- FILE *inputFile=fopen(filename, "rb");
- if(inputFile==NULL) {
- return NULL;
- }
- int resourceBufferSize=BUFSIZ;
- char *resource=(char *)malloc(resourceBufferSize);
- int resourceTotalRead=0;
- while (!feof(inputFile) && !ferror(inputFile)) {
- if (resourceTotalRead+BUFSIZ > resourceBufferSize) {
- if(resourceBufferSize > 10*1024*1024) {
- break;
- }
- resourceBufferSize*=2;
- resource=(char *)realloc(resource, resourceBufferSize);
- }
- char *position=resource+resourceTotalRead;
- resourceTotalRead+=fread(position, 1, BUFSIZ, inputFile);
- }
- fclose(inputFile);
- resource=(char *)realloc(resource, resourceTotalRead+1);
- resource[resourceTotalRead]='\0';
- return resource;
- }
- void printCompilationLog(GLuint objectID) {
- GLint shaderCompilationInfoLogLength = 0;
- glGetShaderiv(objectID, GL_INFO_LOG_LENGTH , &shaderCompilationInfoLogLength);
- GLchar* compilerLog = new GLchar[shaderCompilationInfoLogLength];
- GLsizei slen = 0;
- glGetShaderInfoLog(objectID, shaderCompilationInfoLogLength, &slen, compilerLog);
- fprintf(stderr, "compiler_log: %s", compilerLog);
- delete compilerLog;
- }
- bool bindShaderAttribute(GLint *shaderAttribute, GLuint shaderProgram, const char *shaderAttributeName) {
- *shaderAttribute=glGetAttribLocation(shaderProgram, shaderAttributeName);
- return *shaderAttribute!=-1;
- }
- bool bindShaderUniformAttribute(GLint *shaderAttribute, GLuint shaderProgram, const char *shaderAttributeName){
- *shaderAttribute=glGetUniformLocation(shaderProgram, shaderAttributeName);
- return *shaderAttribute!=-1;
- }
- GLuint createShader(const char *filename, GLenum shaderType) {
- const char *shaderSource=readFile(filename);
- if(shaderSource==NULL) {
- fprintf(stderr, "ERROR: Could not open shader source file: %s", filename);
- return 0;
- }
- GLuint shaderID=glCreateShader(shaderType);
- const GLchar *shaderSources[]={
- // Define GLSL version
- #if defined(EMSCRIPTEN) || defined (GL_ES_VERSION_2_0)
- "#version 100\n"
- #else
- "#version 120\n"
- #endif
- ,
- // GLES2 precision specifiers
- #if defined(EMSCRIPTEN) || defined (GL_ES_VERSION_2_0)
- // Define default float precision for fragment shaders:
- (shaderType == GL_FRAGMENT_SHADER) ?
- "#ifdef GL_FRAGMENT_PRECISION_HIGH\n"
- "precision highp float; \n"
- "#else \n"
- "precision mediump float; \n"
- "#endif \n"
- : ""
- // Note: OpenGL ES automatically defines this:
- // #define GL_ES
- #else
- // Ignore GLES 2 precision specifiers:
- "#define lowp \n"
- "#define mediump\n"
- "#define highp \n"
- #endif
- ,
- shaderSource
- };
- glShaderSource(shaderID, 3, shaderSources, NULL);
- free((void *)shaderSource);
- glCompileShader(shaderID);
- GLint compilationSuccess=GL_FALSE;
- glGetShaderiv(shaderID, GL_COMPILE_STATUS, &compilationSuccess);
- if (compilationSuccess==GL_FALSE) {
- fprintf(stderr, "Shader Compilation Failure\n");
- printCompilationLog(shaderID);
- glDeleteShader(shaderID);
- return 0;
- }
- return shaderID;
- }
- bool initShaders() {
- //load shaders & compile
- GLint linkSuccess=GL_FALSE;
- //vertex shader
- GLuint vertexShaderId=createShader("shaders/vertex.glsl", GL_VERTEX_SHADER);
- //fragment shader
- GLuint fragmentShaderId=createShader("shaders/fragment.glsl", GL_FRAGMENT_SHADER);
- //program
- shaderProgram=glCreateProgram();
- glAttachShader(shaderProgram, vertexShaderId);
- glAttachShader(shaderProgram, fragmentShaderId);
- glLinkProgram(shaderProgram);
- glGetProgramiv(shaderProgram, GL_LINK_STATUS, &linkSuccess);
- if(linkSuccess==GL_FALSE){
- fprintf(stderr, "Shader Linking Failure\n");
- return false;
- }
- //shader attributes
- const char *coord2DAttributeName="coord3D";
- if(!bindShaderAttribute(&shaderAttribute_coord3D, shaderProgram, coord2DAttributeName)){
- fprintf(stderr, "Could not bind shader attribute %s\n", coord2DAttributeName);
- return false;
- }
- const char *vertexColourAttributeName="vertexColour";
- if(!bindShaderAttribute(&shaderAttribute_vertexColour, shaderProgram, vertexColourAttributeName)){
- fprintf(stderr, "Could not bind shader attribute %s\n", vertexColourAttributeName);
- return false;
- }
- const char *mvpMatrixAttributeName="mvp";
- if(!bindShaderUniformAttribute(&shaderAttribute_uniform_mvp, shaderProgram, mvpMatrixAttributeName)){
- fprintf(stderr, "Could not bind shader attribute %s\n", mvpMatrixAttributeName);
- return false;
- }
- const char *animationMatrixAttributeName="animation";
- if(!bindShaderUniformAttribute(&shaderAttribute_uniform_animation, shaderProgram, animationMatrixAttributeName)){
- fprintf(stderr, "Could not bind shader attribute %s\n", animationMatrixAttributeName);
- return false;
- }
- //if nothing fails till here, shader init is a success
- return true;
- }
- struct modelData {
- GLfloat coord3D[3];
- GLfloat colour3D[3];
- };
- void initModels() {
- struct modelData cube[] = {
- //front face
- {{-1.0, -1.0, 1.0}, {0.0, 0.0, 1.0}},
- {{ 1.0, -1.0, 1.0}, {0.0, 1.0, 0.0}},
- {{ 1.0, 1.0, 1.0}, {1.0, 0.0, 0.0}},
- {{-1.0, 1.0, 1.0}, {0.0, 1.0, 0.0}},
- //back face
- {{-1.0, -1.0, -1.0}, {0.0, 1.0, 0.0}},
- {{ 1.0, -1.0, -1.0}, {0.0, 0.0, 1.0}},
- {{ 1.0, 1.0, -1.0}, {0.0, 1.0, 0.0}},
- {{-1.0, 1.0, -1.0}, {1.0, 0.0, 0.0}}
- };
- glGenBuffers(1, &modelDataVBO);
- glBindBuffer(GL_ARRAY_BUFFER, modelDataVBO);
- glBufferData(GL_ARRAY_BUFFER, sizeof(cube), cube, GL_STATIC_DRAW);
- glBindBuffer(GL_ARRAY_BUFFER, 0);
- GLushort cubeElements[] = {
- // front
- 0, 1, 2,
- 2, 3, 0,
- // top
- 1, 5, 6,
- 6, 2, 1,
- // back
- 7, 6, 5,
- 5, 4, 7,
- // bottom
- 4, 0, 3,
- 3, 7, 4,
- // left
- 4, 5, 1,
- 1, 0, 4,
- // right
- 3, 2, 6,
- 6, 7, 3,
- };
- glGenBuffers(1, &modelElements);
- glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, modelElements);
- glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(cubeElements), cubeElements, GL_STATIC_DRAW);
- glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
- }
- bool initResources() {
- initModels();
- return initShaders();
- }
- void freeResources() {
- glDeleteProgram(shaderProgram);
- //delete models
- glDeleteBuffers(1, &modelDataVBO);
- }
- void render() {
- //clear screen
- glClearColor(1.0, 1.0, 1.0, 1.0);
- glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
- //use the shader
- glUseProgram(shaderProgram);
- //enable attributes in program
- glEnableVertexAttribArray(shaderAttribute_coord3D);
- glEnableVertexAttribArray(shaderAttribute_vertexColour);
- //describe arrays to program
- glBindBuffer(GL_ARRAY_BUFFER, modelDataVBO);
- glVertexAttribPointer(shaderAttribute_coord3D, // attribute
- 3, // number of elements per vertex, here (x,y)
- GL_FLOAT, // the type of each element
- GL_FALSE, // take our values as-is
- sizeof(struct modelData), // 2d coord every 5 elements
- 0 // offset of first element
- );
- glBindBuffer(GL_ARRAY_BUFFER, modelDataVBO);
- glVertexAttribPointer(shaderAttribute_vertexColour, // attribute
- 3, // number of elements per vertex, here (r,g,b)
- GL_FLOAT, // the type of each element
- GL_FALSE, // take our values as-is
- sizeof(struct modelData), // colour every 5 elements
- (GLvoid *)(offsetof(struct modelData, colour3D)) // skip 2d coords
- );
- //draw the cube by going through its elements array
- glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, modelElements);
- int bufferSize;
- glGetBufferParameteriv(GL_ELEMENT_ARRAY_BUFFER, GL_BUFFER_SIZE, &bufferSize);
- glDrawElements(GL_TRIANGLES, bufferSize/sizeof(GLushort), GL_UNSIGNED_SHORT, 0);
- //close up the attribute in program, no more need
- glDisableVertexAttribArray(shaderAttribute_coord3D);
- glDisableVertexAttribArray(shaderAttribute_vertexColour);
- //blit drawn screen
- glutSwapBuffers();
- }
- void reshape(int newWindowWidth, int newWindowHeight)
- {
- windowWidth=newWindowWidth;
- windowHeight=newWindowHeight;
- glViewport(0, 0, windowWidth, windowHeight);
- }
- void idle()
- {
- //model matrix using model position vector
- glm::vec3 modelPosition=glm::vec3(0,0,-4);
- glm::mat4 model=glm::translate(glm::mat4(1.0f), modelPosition);
- //view matrix using look at
- glm::vec3 cameraPosition=glm::vec3(0,2,0);
- glm::vec3 cameraTarget=glm::vec3(0,0,-4); //same as model position to look at model
- glm::vec3 cameraUp=glm::vec3(0,1,0);
- glm::mat4 view=glm::lookAt(cameraPosition, cameraTarget, cameraUp);
- //projection matrix
- GLfloat lensAngle=45.0f;
- GLfloat aspectRatio=1.0*(windowWidth/windowHeight);
- GLfloat nearClippingPlane=0.1f;
- GLfloat farClippingPlane=10.0f;
- glm::mat4 projection=glm::perspective(lensAngle, aspectRatio, nearClippingPlane, farClippingPlane);
- glm::mat4 mvp=projection*view*model;
- glUniformMatrix4fv(shaderAttribute_uniform_mvp, 1, GL_FALSE, glm::value_ptr(mvp));
- //animation matrix
- float angle = glutGet(GLUT_ELAPSED_TIME) / 1000.0 * 45; // 45° per second
- glm::vec3 axis(1.0, -1.0, 0.0);
- glm::mat4 anim = glm::rotate(glm::mat4(1.0f), angle, axis);
- glUniformMatrix4fv(shaderAttribute_uniform_animation, 1, GL_FALSE, glm::value_ptr(anim));
- glutPostRedisplay();
- }
- int main(int argc, char* argv[]) {
- glutInit(&argc, argv);
- glutInitDisplayMode(GLUT_RGBA|GLUT_ALPHA|GLUT_DOUBLE|GLUT_DEPTH);
- glutInitWindowSize(windowWidth, windowHeight);
- glutCreateWindow("Voxels");
- glEnable(GL_BLEND);
- glEnable(GL_DEPTH_TEST);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- if(initResources()==true){
- glutReshapeFunc(reshape);
- glutDisplayFunc(render);
- glutIdleFunc(idle);
- glutMainLoop();
- }
- freeResources();
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement