Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include "include/GL/glew.h"
- #include "include/GL/glut.h"
- #include <iostream>
- #include"include/GLM/GLM/glm.hpp"
- //using glm::mat4;
- //using glm::vec3;
- #include"include/GLM/GLM/gtc/matrix_transform.hpp"
- using namespace glm;
- float angle = 45.0f;
- float orbit = 0.0f;
- //! ID шейдерной программы
- GLuint Program;
- //! ID Vertex Buffer Object
- GLuint uVAO, uVBO[4];
- void render();
- //! Вершина
- struct vertex
- {
- GLfloat x;
- GLfloat y;
- GLfloat z;
- };
- //! Функция печати лога шейдера
- void shaderLog(unsigned int shader)
- {
- int infologLen = 0;
- int charsWritten = 0;
- char *infoLog;
- glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infologLen);
- if(infologLen > 1)
- {
- infoLog = new char[infologLen];
- if(infoLog == NULL)
- {
- std::cout<<"ERROR: Could not allocate InfoLog buffer\n";
- exit(1);
- }
- glGetShaderInfoLog(shader, infologLen, &charsWritten, infoLog);
- std::cout<< "InfoLog: " << infoLog << "\n\n\n";
- delete[] infoLog;
- }
- }
- //! Инициализация OpenGL, здесь пока по минимальному=)
- void initGL()
- {
- glClearColor(0, 0, 0, 0);
- }
- //! Проверка ошибок OpenGL, если есть то выводит в консоль тип ошибки
- void checkOpenGLerror()
- {
- GLenum errCode;
- if((errCode=glGetError()) != GL_NO_ERROR)
- std::cout << "OpenGl error! - " << gluErrorString(errCode);
- }
- //! Инициализация шейдеров
- void initShader()
- {
- //! Исходный код шейдеров
- const char* vsSource =
- "#version 330\n"
- "uniform mat4 mWorld;"
- "uniform mat4 mView;"
- "uniform mat4 mProjection;\n "
- "uniform vec3 vLightPos[3];\n"
- "uniform vec3 vLightColor[3];\n"
- "layout (location=0) in vec3 inPosition;\n"
- "layout (location=1) in vec3 inColor;\n"
- "layout (location=2) in vec3 inNormal;\n"
- " out vec3 theColor;\n"
- "void main() {\n"
- "gl_Position = mProjection*mView*mWorld*vec4(inPosition*4.0f, 1.0);\n"
- "vec3 color_tm=vec3(0.0);\n"
- "for (int i=0; i<3; i++)\n"
- "{ color_tm+=dot(normalize(inNormal),normalize(vec3(vLightPos[i] - inPosition)))*vLightColor[i] * 0.5;\n"
- "}\n"
- "theColor=color_tm;\n "
- "}\n";
- /*const char* vsSource =
- "#version 330\n"
- "uniform mat4 mWorld;"
- "uniform mat4 mView;"
- "uniform mat4 mProjection;\n "
- "uniform vec3 vLightPos[3];\n"
- "uniform vec3 vLightColor[3];\n"
- "layout (location=0) in vec3 inPosition;\n"
- "layout(location=1) in vec3 inColor;\n"
- "layout(location = 2) in vec3 inNormal; \n"
- " out vec3 theColor;\n"
- "void main() {\n"
- "gl_Position = mProjection*mView*mWorld*vec4(inPosition*4.0f, 1.0);\n"
- "vec3 color = inColor;\n"
- "for (int i=0;i<3;i++)\n"
- "color+ = dot(normalize(inNormal),normalize(vLightPos[i]-inPosition))*vLightColor[i]*0.5f;\n"
- "theColor =color;\n "
- "}\n"; */
- const char* fsSource =
- "#version 330\n"
- "in vec3 theColor;\n"
- "layout(location=0) out vec4 outputColor;\n"
- "void main(){\n"
- "outputColor=vec4(theColor,1.0);\n"
- "}\n";
- //! Переменные для хранения идентификаторов шейдеров
- GLuint vShader, fShader;
- //! Создаем вершинный шейдер
- vShader = glCreateShader(GL_VERTEX_SHADER);
- //! Передаем исходный код
- glShaderSource(vShader, 1, &vsSource, NULL);
- //! Компилируем шейдер
- glCompileShader(vShader);
- std::cout << "vertex shader \n";
- shaderLog(vShader);
- //! Создаем фрагментный шейдер
- fShader = glCreateShader(GL_FRAGMENT_SHADER);
- //! Передаем исходный код
- glShaderSource(fShader, 1, &fsSource, NULL);
- //! Компилируем шейдер
- glCompileShader(fShader);
- std::cout << "fragment shader \n";
- shaderLog(fShader);
- //! Создаем программу и прикрепляем шейдеры к ней
- Program = glCreateProgram();
- glAttachShader(Program, vShader);
- glAttachShader(Program, fShader);
- //! Линкуем шейдерную программу
- glLinkProgram(Program);
- //! Проверяем статус сборки
- int link_ok;
- glGetProgramiv(Program, GL_LINK_STATUS, &link_ok);
- if(!link_ok)
- {
- std::cout << "error attach shaders \n";
- return;
- }
- checkOpenGLerror();
- }
- //! Инициализация VBO
- void initVBO()
- {
- //! Вершины нашего треугольника
- vertex triangle[] = {
- -0.5f, 0.5f, 0.0f, // Top-left
- 0.5f, 0.5f, 0.0f, // Top-right
- 0.5f, -0.5f, 0.0f, // Bottom-right
- -0.5f, -0.5f, 0.0f, // Bottom-left
- 0.f, 1.f, 0.0f // Top top
- };
- vertex color[] = {
- 0.75f, 0.75f, 0.75f,
- 0.0f, 1.0f, 0.0f,
- 0.0f, 1.0f, 1.0f,
- 1.0f, 1.0f, 0.0f,
- 1.0f, 1.0f, 1.0f
- };
- int index[9] = { 0, 4, 1, 0, 1, 2, 2, 3, 0 };
- vertex normal[6] = {
- { 1, 0, 1 },
- { 1, 0, 0 },
- { 0, 1, 0 }
- };
- glGenVertexArrays(1, &uVAO);
- glGenBuffers(4,uVBO);
- glBindVertexArray(uVAO);
- glBindBuffer(GL_ARRAY_BUFFER, uVBO[0]);
- glBufferData(GL_ARRAY_BUFFER, 27 * sizeof(float), triangle, GL_STATIC_DRAW);
- glEnableVertexAttribArray(0);
- glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, NULL);
- glBindBuffer(GL_ARRAY_BUFFER, uVBO[1]);
- glBufferData(GL_ARRAY_BUFFER, 27 * sizeof(float), color, GL_STATIC_DRAW);
- glEnableVertexAttribArray(1);
- glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0,NULL);
- glBindBuffer(GL_ARRAY_BUFFER, uVBO[2]);
- glBufferData(GL_ARRAY_BUFFER, 6 * sizeof(float), normal, GL_STATIC_DRAW);
- glEnableVertexAttribArray(2);
- glVertexAttribPointer(2,3, GL_FLOAT, GL_FALSE, 0, NULL);
- glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, uVBO[3]);
- glBufferData(GL_ELEMENT_ARRAY_BUFFER, 9*sizeof(int),index, GL_STATIC_DRAW);
- checkOpenGLerror();
- }
- //! Освобождение шейдеров
- void freeShader()
- {
- //! Передавая ноль, мы отключаем шейдрную программу
- glUseProgram(0);
- //! Удаляем шейдерную программу
- glDeleteProgram(Program);
- }
- //! Освобождение шейдеров
- void freeVBO()
- {
- // glBindBuffer(GL_ARRAY_BUFFER, 0);
- glDeleteBuffers(3, uVBO);
- glDeleteVertexArrays(1, &uVAO);
- }
- void resizeWindow(int width, int height)
- {
- glViewport(0, 0, width, height);
- }
- //! Отрисовка
- void render()
- {
- glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
- glEnable(GL_DEPTH_TEST);
- //! Устанавливаем шейдерную программу текущей
- glUseProgram(Program);
- // Изменение позиции камеры на орбите
- float radius = 5.0f;
- //orbit += 0.001f;
- // Инициализация орбитальных данных координат камеры
- glm::vec3 Eye(sin(orbit)*radius, 1.0f, -2.0f + cos(orbit)*radius*2.0f);//поменять на spin
- //Установка матриц для камеры
- glm::mat4 mWorld;
- glm::mat4 mView;
- glm::mat4 mProjection;
- mWorld = glm::mat4(1.0f, 0, 0, 0, 0, 1.0f, 0, 0, 0, 0, 1.0f, 0, 0, 0, 0, 1.0f);
- mWorld = glm::translate(mWorld,glm::vec3(0, 0, 0));
- mWorld = glm::rotate(mWorld, orbit,vec3(0, 0, 1));
- mView = glm::lookAt(Eye, glm::vec3(0, 0, 0), glm::vec3(0.0f, 1.0f, 0.0f));
- mProjection = glm::perspectiveFov(45.0f, 533.0f, 400.0f, 0.01f, 100.0f);
- //Установка констант шейдера матриц
- int iWorld = glGetUniformLocation(Program, "mWorld");
- int iView = glGetUniformLocation(Program, "mView");
- int iProjection = glGetUniformLocation(Program, "mProjection");
- glUniformMatrix4fv(iWorld, 1, GL_FALSE, &mWorld[0][0]);
- glUniformMatrix4fv(iView, 1, GL_FALSE, &mView[0][0]);
- glUniformMatrix4fv(iProjection, 1, GL_FALSE, &mProjection[0][0]);
- float f0 = 2.0f;
- float f1 = 3.0f;
- float f2 = 2.5f;
- float r = 3.0f;
- // Установка координат источников освещения
- glm::vec3 LightPos[3];
- glm::vec3 LightColor[3];
- LightPos[0] = glm::vec3(sin(orbit*f0)*r, cos(orbit*f0)*r, cos(orbit*f0)*r);
- LightPos[1] = glm::vec3(sin(orbit*f1)*r, -sin(orbit*f1)*r, -cos(orbit*f1)*r);
- LightPos[2] = glm::vec3(cos(orbit*f2)*r, sin(orbit*f2)*r, sin(orbit*f2)*r);
- LightColor[0] = glm::vec3(1, 1, 0);
- LightColor[1] = glm::vec3(0, 0, 1);
- LightColor[2] = glm::vec3(0, 1, 1);
- // Установка констант шейдера для источников
- int iLightPos = glGetUniformLocation(Program, "vLightPos");
- int iLightColor = glGetUniformLocation(Program, "vLightColor");
- glUniform3fv(iLightPos, 3,&LightPos[0][0]);
- glUniform3fv(iLightColor, 3,&LightColor[0][0]);
- glBindVertexArray(uVAO);
- //! Передаем данные на видеокарту(рисуем)
- glDrawElements(GL_TRIANGLES, 9 , GL_UNSIGNED_INT, 0);
- mWorld = glm::mat4(1.0f, 0, 0, 0, 0, 1.0f, 0, 0, 0, 0, 1.0f, 0, 0, 0, 0, 1.0f);
- mWorld = glm::translate(mWorld,glm::vec3(4.0f, 0.0f, 0.0f));
- //mWorld = glm::rotate(mWorld, spin, vec3(0, 0, 1));
- glUniformMatrix4fv(iWorld, 1, GL_FALSE, &mWorld[0][0]);
- glBindVertexArray(uVAO);
- //! Передаем данные на видеокарту(рисуем)
- //glDrawElements(GL_TRIANGLES, 15, GL_UNSIGNED_INT, 0);
- //! Отключаем шейдерную программу
- glUseProgram(0);
- checkOpenGLerror();
- glutSwapBuffers();
- }
- void processSpecialKeys(int key, int x, int y) {
- switch(key) {
- case GLUT_KEY_LEFT :
- orbit -= 0.05f;
- break;
- case GLUT_KEY_RIGHT :
- orbit += 0.05f;
- break;
- }
- }
- int main( int argc, char **argv )
- {
- glutInit(&argc, argv);
- glutInitDisplayMode(GLUT_RGBA | GLUT_ALPHA | GLUT_DOUBLE);
- glutInitWindowSize(800, 600);
- glutCreateWindow("Simple shaders");
- //! Обязательно перед инициализации шейдеров
- GLenum glew_status = glewInit();
- if(GLEW_OK != glew_status)
- {
- //! GLEW не проинициализировалась
- std::cout << "Error: " << glewGetErrorString(glew_status) << "\n";
- return 1;
- }
- //! Проверяем доступность OpenGL 2.0
- if(!GLEW_VERSION_2_0)
- {
- //! OpenGl 2.0 оказалась не доступна
- std::cout << "No support for OpenGL 2.0 found\n";
- return 1;
- }
- //! Инициализация
- initGL();
- initVBO();
- initShader();
- glutReshapeFunc(resizeWindow);
- glutDisplayFunc(render);
- glutIdleFunc(render);
- glutSpecialFunc(processSpecialKeys);
- glutMainLoop();
- //! Освобождение ресурсов
- freeShader();
- freeVBO();
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement