1, General Method
#define GLEW_STATIC // GLEW #include <GL/glew.h> #include <cstdlib> #undef GLFW_DLL // GLFW #include <GLFW/glfw3.h> #include <iostream> #include "ALG_LoadShader.h" #include "ALG_LoadTexture.h" #include "ALG_GLFWCamera.h" #include "ALG_FrameWindow.h" #include "ALG_ModelDelegate.h" #include "ALG_SceneDelegate.h" #include "ALG_DrawGrid.h" #include "ALG_DrawOriginGnomon.h" #include "ALG_DrawPostPocessingQuad.h" #include "ALG_DrawPlane.h" #include "ALG_DepthShadow.h" #include "ALG_OGLHelper.h" #include "ALG_DirLight.h" #include "ALG_SceneLocation.h" #include <cmath> #include "ALG_Random.h" #include <glm/glm.hpp> #include <glm/gtc/matrix_transform.hpp> #include <glm/gtc/type_ptr.hpp> #include "ALG_FPS.h" using namespace AlgebraMaster; const unsigned int SRC_WIDTH = 900; const unsigned int SRC_HEIGHT = 900; void init(); void display(); void processInput(GLFWwindow *window); void framebuffer_size_callback(GLFWwindow* window, int width, int height); // framezize void mouse_callback(GLFWwindow* window, double xpos, double ypos); // Maya Alt+LeftMouse void scroll_callback(GLFWwindow *window, double xoffset, double yoffset); // camera static GLFWCamera *camera; static float lastX = float(SRC_WIDTH) / 2.0f; static float lastY = float(SRC_HEIGHT) / 2.0f; static bool firstMouse = true; static bool firstMiddowMouse = true; // timing static float deltaTime = 0.0f; // time between current frame and last frame static float lastFrame = 0.0f; static FrameWindow *frameWindow ; // per geometry verticles static float verticles[] = { -0.1f, 0.1f, -0.1f, -0.1f, 0.1f, -0.1f, 0.1f, 0.1f }; static GLuint indices[] = { 0 , 1 , 2, 0 , 2 , 3 }; static GLuint VAO,VBO,EBO; static GLuint INST_COLOR_BUFFER, INST_MAT_BUFFER; static int INSTANCE_COUNT = 300; static LoadShader shader; void init(){ glViewport(0,0,SRC_WIDTH,SRC_HEIGHT); if(!CheckExtension("GL_ARB_shading_language_include")){ cout << "---------------ERROR:: SHADER DO NOT SUPPORT INCLUDE SHADER---------------------------------- "; } AddCommonShaderFile("shaders/common/material_interface.glsl"); AddCommonShaderFile("shaders/common/light_interface.glsl"); AddCommonShaderFile("shaders/common/shadow.glsl"); AddCommonShaderFile("shaders/common/utils.glsl"); AddCommonShaderFile("shaders/common/postprocess.glsl"); shader.load("shaders/advanced_instance/part1/surface.vert","shaders/advanced_instance/part1/surface.frag"); camera = new GLFWCamera; camera->pos.y = 0.5f; camera->pos.z = 2.0f; // Create VAO glCreateVertexArrays(1,&VAO); glBindVertexArray(VAO); // set vertex buffer object data glCreateBuffers(1,&VBO); glBindBuffer(GL_ARRAY_BUFFER, VBO); glBufferData(GL_ARRAY_BUFFER,sizeof(verticles),verticles,GL_STATIC_DRAW ); // local position glEnableVertexAttribArray(0); glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, (void*)0); // stride = 0 , offset = void* 0 // create element buffer object glCreateBuffers(1,&EBO); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO); glBufferData(GL_ELEMENT_ARRAY_BUFFER,sizeof(indices), indices, GL_STATIC_DRAW); // create color [-1,1] , but in this default buffer not support HDR , just ignore it RandomN1P1 r(INSTANCE_COUNT, 1321); RandomN1P1 g(INSTANCE_COUNT, 321321); RandomN1P1 b(INSTANCE_COUNT,231); glm::vec3 *colors = new glm::vec3[INSTANCE_COUNT]; for(int i=0;i<INSTANCE_COUNT;i++){ colors[i].r = r[i]; colors[i].g = g[i]; colors[i].b = b[i]; } glCreateBuffers(1,&INST_COLOR_BUFFER); glBindBuffer(GL_ARRAY_BUFFER,INST_COLOR_BUFFER); glBufferData(GL_ARRAY_BUFFER,sizeof(glm::vec3) * INSTANCE_COUNT, &colors[0],GL_STATIC_DRAW); glEnableVertexAttribArray(1); glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(glm::vec3), (void*)0); glVertexAttribDivisor(1, 1); // create matrix glCreateBuffers(1,&INST_COLOR_BUFFER); glBindBuffer(GL_ARRAY_BUFFER,INST_COLOR_BUFFER); glm::mat4 *mats = new glm::mat4[INSTANCE_COUNT]; // generator [-1,1] range RandomN1P1 xPosSet(INSTANCE_COUNT, 2312); RandomN1P1 yPosSet(INSTANCE_COUNT, 42); RandomN1P1 zPosSet(INSTANCE_COUNT, 31513); RandomN1P1 rotAmount(INSTANCE_COUNT,523); Random01 scaleAmount(INSTANCE_COUNT,3213); for(int i=0;i<INSTANCE_COUNT;i++){ // new translate glm::mat4 model(1.0f); model = glm::translate(model,glm::vec3(xPosSet[i], yPosSet[i], zPosSet[i] ) ); // new rot glm::mat4 rot(1.0f); rot = glm::rotate(rot,glm::radians(rotAmount[i]*360) , glm::vec3(0.0,0.0,1.0)); // R S T order glm::mat4 scale(1.0f); scale = glm::scale( scale,glm::vec3(scaleAmount[i]) ); mats[i] = model * scale * rot ; } glCreateBuffers(1,&INST_MAT_BUFFER); glBindBuffer(GL_ARRAY_BUFFER,INST_MAT_BUFFER); glBufferData(GL_ARRAY_BUFFER,sizeof(glm::mat4) * INSTANCE_COUNT, &mats[0],GL_STATIC_DRAW); // first column glEnableVertexAttribArray(2); glVertexAttribPointer(2, 4, GL_FLOAT, GL_FALSE, sizeof(glm::mat4), (void*)0); // second column glEnableVertexAttribArray(3); glVertexAttribPointer(3, 4, GL_FLOAT, GL_FALSE, sizeof(glm::mat4), (void*)(sizeof(glm::vec4))); // third column glEnableVertexAttribArray(4); glVertexAttribPointer(4, 4, GL_FLOAT, GL_FALSE, sizeof(glm::mat4), (void*)(2 * sizeof(glm::vec4))); // fourth column glEnableVertexAttribArray(5); glVertexAttribPointer(5, 4, GL_FLOAT, GL_FALSE, sizeof(glm::mat4), (void*)(3 * sizeof(glm::vec4))); glVertexAttribDivisor(2, 1); glVertexAttribDivisor(3, 1); glVertexAttribDivisor(4, 1); glVertexAttribDivisor(5, 1); } // ----------- Render Loop ---------- void display(){ int display_w, display_h; glfwGetFramebufferSize(frameWindow->getWindow(), &display_w, &display_h); // Rendering objs Loop ClearAllBufferColor(); glBindVertexArray(VAO); shader.use(); glDrawElementsInstanced(GL_TRIANGLES,6, GL_UNSIGNED_INT, nullptr, INSTANCE_COUNT); // 6 is our indices num //glDrawElements(GL_TRIANGLES,6,GL_UNSIGNED_INT, 0); } int main() { glfwInit(); frameWindow = new FrameWindow(SRC_WIDTH,SRC_HEIGHT); glfwSetFramebufferSizeCallback(frameWindow->getWindow(), framebuffer_size_callback); glfwSetCursorPosCallback(frameWindow->getWindow(),mouse_callback); glfwSetScrollCallback(frameWindow->getWindow(), scroll_callback); init(); //double lastTime = glfwGetTime(); //double targetFps = 60.0f; FPSLimit fpsLimit; fpsLimit.targetFps = 60.02f; FPSGet fpsGet; //double previousTime = glfwGetTime(); //double frameCount = 0; // RENDER-------------- // draw as wireframe //glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); while(!glfwWindowShouldClose(frameWindow->getWindow())){ processInput(frameWindow->getWindow()); fpsLimit.limitFPS(); fpsGet.updateFPS(frameWindow->getWindow()); display(); // Rendering objs Loop int display_w, display_h; glfwGetFramebufferSize(frameWindow->getWindow(), &display_w, &display_h); glViewport(0, 0, display_w, display_h); glfwSwapBuffers(frameWindow->getWindow()); glfwPollEvents(); } delete camera; return 0; } void framebuffer_size_callback(GLFWwindow* window, int width, int height) { // make sure the viewport matches the new window dimensions; note that width and // height will be significantly larger than specified on retina displays. glViewport(0, 0, width, height); } void processInput(GLFWwindow *window) { if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS) glfwSetWindowShouldClose(window, true); if (glfwGetKey(window, GLFW_KEY_W) == GLFW_PRESS) camera->processKeyboardMove(deltaTime,GLFWCamera::FORWARD); if (glfwGetKey(window, GLFW_KEY_S) == GLFW_PRESS) camera->processKeyboardMove(deltaTime,GLFWCamera::BACKWARD); if (glfwGetKey(window, GLFW_KEY_A) == GLFW_PRESS) camera->processKeyboardMove(deltaTime,GLFWCamera::LEFT); if (glfwGetKey(window, GLFW_KEY_D) == GLFW_PRESS) camera->processKeyboardMove(deltaTime,GLFWCamera::RIGHT); } // ROTATE VIEW DIR void mouse_callback(GLFWwindow* window, double xpos, double ypos){ int middow_mouse_state = glfwGetMouseButton(window,GLFW_MOUSE_BUTTON_MIDDLE); int mouse_state = glfwGetMouseButton(window,GLFW_MOUSE_BUTTON_LEFT); int key_state = glfwGetKey(window,GLFW_KEY_LEFT_ALT); // set up the camera view if( mouse_state == GLFW_PRESS && key_state== GLFW_PRESS) { if (firstMouse){ lastX = xpos; lastY = ypos; firstMouse = false; } float xoffset = xpos - lastX; float yoffset = lastY - ypos; // reversed since y-coordinates go from bottom to top lastX = xpos; lastY = ypos; camera->processMouseMove(xoffset,yoffset); } if (key_state == GLFW_RELEASE || mouse_state == GLFW_RELEASE){ firstMouse = true; } // Move Camera Position if( middow_mouse_state == GLFW_PRESS) { if (firstMiddowMouse){ lastX = xpos; lastY = ypos; firstMiddowMouse = false; } float xoffset = xpos - lastX; float yoffset = lastY - ypos; // reversed since y-coordinates go from bottom to top lastX = xpos; lastY = ypos; camera->pos.x += xoffset*0.01f; camera->pos.y += yoffset*0.01f; } if ( middow_mouse_state == GLFW_RELEASE){ firstMiddowMouse = true; } } void scroll_callback(GLFWwindow *window, double xoffset, double yoffset){ camera->processFov(yoffset); }
#version 450 core layout ( location = 0 ) in vec2 vPosition; // c++ pos layout ( location = 1 ) in vec3 vColor; // instance color layout ( location = 2 ) in mat4 vModelMatrix; // instance matrix , 2,3,4,5 out VERTEX{ vec3 color; }vertex; void main(){ gl_Position = vModelMatrix * vec4(vPosition.x, vPosition.y, 0.0, 1.0); vertex.color = vColor; }
#version 450 core out vec4 FragColor; in VERTEX{ vec3 color; }vertex; void main() { FragColor = vec4(vertex.color,1.0); // set alle 4 vector values to 1.0 }
// // Created by Admin on 2020/3/7. // #ifndef TRIANGLE_ALG_RANDOM_H #define TRIANGLE_ALG_RANDOM_H #include <glm/glm.hpp> #include <glm/gtc/matrix_transform.hpp> #include <glm/gtc/type_ptr.hpp> #include <random> #include <iostream> #include <vector> #include <iostream> #include <limits> #include <random> namespace AlgebraMaster { using namespace std; // ------------- Float 0-1 Random gen------------------------ struct RandomFloatBase{ explicit RandomFloatBase(int num, int seed=1){ } // datas vector<float> values; default_random_engine e; uniform_real_distribution<double> u; float operator[] (int index)const{ return values[index]; } float &operator[] (int index){ return values[index]; } friend ostream & operator << (ostream &os , const RandomFloatBase &rv){ for(auto &v:rv.values){ cout << v <<" "; } cout << " "; return os; } }; struct Random01:public RandomFloatBase{ Random01(int num,int seed=1); }; Random01::Random01(int num,int seed): RandomFloatBase(num, seed){ e.seed(seed); u = uniform_real_distribution<double>(0.0,1.0); for(int i=0;i<num;i++){ values.emplace_back(u(e)); } } // ------------- Float 0-1 Random gen------------------------ // ------------- Float -1 - 1 Random gen------------------------ struct RandomN1P1:public RandomFloatBase{ explicit RandomN1P1(int num,int seed=1); }; RandomN1P1::RandomN1P1(int num,int seed): RandomFloatBase(num, seed){ e.seed(seed); u = uniform_real_distribution<double>(-1.0,1.0); for(int i=0;i<num;i++){ values.emplace_back(u(e)); } } } // namespace end #endif //TRIANGLE_ALG_RANDOM_H
这里面最后要释放color和mats这两个数组。
主要的绘制命令就:
// ----------- Render Loop ---------- void display(){ int display_w, display_h; glfwGetFramebufferSize(frameWindow->getWindow(), &display_w, &display_h); // Rendering objs Loop ClearAllBufferColor(); glBindVertexArray(VAO); shader.use(); glDrawElementsInstanced(GL_TRIANGLES,6, GL_UNSIGNED_INT, nullptr, INSTANCE_COUNT); // 6 is our indices num //glDrawElements(GL_TRIANGLES,6,GL_UNSIGNED_INT, 0); }
2,General Method With glMapBuffer()
这里直接映射glBufferData(),首先设置数据为NULL,但是要在glBufferData()开辟正常的大小。然后glMapBuffer(),最后再glUnmapBuffer()
这个方法按道理效率更高点,省的new()出来这些内存,后面还要析构这些内存
这个方法也不用改材质
#define GLEW_STATIC // GLEW #include <GL/glew.h> #include <cstdlib> #undef GLFW_DLL // GLFW #include <GLFW/glfw3.h> #include <iostream> #include "ALG_LoadShader.h" #include "ALG_LoadTexture.h" #include "ALG_GLFWCamera.h" #include "ALG_FrameWindow.h" #include "ALG_ModelDelegate.h" #include "ALG_SceneDelegate.h" #include "ALG_DrawGrid.h" #include "ALG_DrawOriginGnomon.h" #include "ALG_DrawPostPocessingQuad.h" #include "ALG_DrawPlane.h" #include "ALG_DepthShadow.h" #include "ALG_OGLHelper.h" #include "ALG_DirLight.h" #include "ALG_SceneLocation.h" #include <cmath> #include "ALG_Random.h" #include <glm/glm.hpp> #include <glm/gtc/matrix_transform.hpp> #include <glm/gtc/type_ptr.hpp> #include "ALG_FPS.h" using namespace AlgebraMaster; const unsigned int SRC_WIDTH = 900; const unsigned int SRC_HEIGHT = 900; void init(); void display(); void processInput(GLFWwindow *window); void framebuffer_size_callback(GLFWwindow* window, int width, int height); // framezize void mouse_callback(GLFWwindow* window, double xpos, double ypos); // Maya Alt+LeftMouse void scroll_callback(GLFWwindow *window, double xoffset, double yoffset); // camera static GLFWCamera *camera; static float lastX = float(SRC_WIDTH) / 2.0f; static float lastY = float(SRC_HEIGHT) / 2.0f; static bool firstMouse = true; static bool firstMiddowMouse = true; // timing static float deltaTime = 0.0f; // time between current frame and last frame static float lastFrame = 0.0f; static FrameWindow *frameWindow ; // per geometry verticles static float verticles[] = { -0.1f, 0.1f, -0.1f, -0.1f, 0.1f, -0.1f, 0.1f, 0.1f }; static GLuint indices[] = { 0 , 1 , 2, 0 , 2 , 3 }; static GLuint VAO,VBO,EBO; static GLuint INST_COLOR_BUFFER, INST_MAT_BUFFER; static int INSTANCE_COUNT = 300; static LoadShader shader; void init(){ glViewport(0,0,SRC_WIDTH,SRC_HEIGHT); if(!CheckExtension("GL_ARB_shading_language_include")){ cout << "---------------ERROR:: SHADER DO NOT SUPPORT INCLUDE SHADER---------------------------------- "; } AddCommonShaderFile("shaders/common/material_interface.glsl"); AddCommonShaderFile("shaders/common/light_interface.glsl"); AddCommonShaderFile("shaders/common/shadow.glsl"); AddCommonShaderFile("shaders/common/utils.glsl"); AddCommonShaderFile("shaders/common/postprocess.glsl"); shader.load("shaders/advanced_instance/part2/surface.vert","shaders/advanced_instance/part2/surface.frag"); camera = new GLFWCamera; camera->pos.y = 0.5f; camera->pos.z = 2.0f; // Create VAO glCreateVertexArrays(1,&VAO); glBindVertexArray(VAO); // set vertex buffer object data glCreateBuffers(1,&VBO); glBindBuffer(GL_ARRAY_BUFFER, VBO); glBufferData(GL_ARRAY_BUFFER,sizeof(verticles),verticles,GL_STATIC_DRAW ); // local position glEnableVertexAttribArray(0); glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, (void*)0); // stride = 0 , offset = void* 0 // create element buffer object glCreateBuffers(1,&EBO); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO); glBufferData(GL_ELEMENT_ARRAY_BUFFER,sizeof(indices), indices, GL_STATIC_DRAW); // create color [-1,1] , but in this default buffer not support HDR , just ignore it glCreateBuffers(1,&INST_COLOR_BUFFER); glBindBuffer(GL_ARRAY_BUFFER,INST_COLOR_BUFFER); glBufferData(GL_ARRAY_BUFFER,sizeof(glm::vec3) * INSTANCE_COUNT, nullptr,GL_STATIC_DRAW); // default we set null data glm::vec3 *colors = (glm::vec3*) glMapBuffer(GL_ARRAY_BUFFER,GL_WRITE_ONLY); // construct instance color data RandomN1P1 r(INSTANCE_COUNT, 1321); RandomN1P1 g(INSTANCE_COUNT, 321321); RandomN1P1 b(INSTANCE_COUNT,231); //glm::vec3 *colors = new glm::vec3[INSTANCE_COUNT]; for(int i=0;i<INSTANCE_COUNT;i++){ colors[i].r = r[i]; colors[i].g = g[i]; colors[i].b = b[i]; } glUnmapBuffer(GL_ARRAY_BUFFER); // !IMPORTANT unmap the GL_ARRAY_BUFFER // send color instance to shader glEnableVertexAttribArray(1); glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(glm::vec3), (void*)0); glVertexAttribDivisor(1, 1); glCreateBuffers(1,&INST_MAT_BUFFER); glBindBuffer(GL_ARRAY_BUFFER,INST_MAT_BUFFER); glBufferData(GL_ARRAY_BUFFER,sizeof(glm::mat4) * INSTANCE_COUNT, nullptr,GL_STATIC_DRAW); glm::mat4 *mats = (glm::mat4*) glMapBuffer(GL_ARRAY_BUFFER,GL_WRITE_ONLY); // generator [-1,1] range RandomN1P1 xPosSet(INSTANCE_COUNT, 2312); RandomN1P1 yPosSet(INSTANCE_COUNT, 42); RandomN1P1 zPosSet(INSTANCE_COUNT, 31513); RandomN1P1 rotAmount(INSTANCE_COUNT,523); Random01 scaleAmount(INSTANCE_COUNT,3213); for(int i=0;i<INSTANCE_COUNT;i++){ // new translate glm::mat4 model(1.0f); model = glm::translate(model,glm::vec3(xPosSet[i], yPosSet[i], zPosSet[i] ) ); // new rot glm::mat4 rot(1.0f); rot = glm::rotate(rot,glm::radians(rotAmount[i]*360) , glm::vec3(0.0,0.0,1.0)); // R S T order glm::mat4 scale(1.0f); scale = glm::scale( scale,glm::vec3(scaleAmount[i]) ); mats[i] = model * scale * rot ; } glUnmapBuffer(GL_ARRAY_BUFFER); // first column glEnableVertexAttribArray(2); glVertexAttribPointer(2, 4, GL_FLOAT, GL_FALSE, sizeof(glm::mat4), (void*)0); // second column glEnableVertexAttribArray(3); glVertexAttribPointer(3, 4, GL_FLOAT, GL_FALSE, sizeof(glm::mat4), (void*)(sizeof(glm::vec4))); // third column glEnableVertexAttribArray(4); glVertexAttribPointer(4, 4, GL_FLOAT, GL_FALSE, sizeof(glm::mat4), (void*)(2 * sizeof(glm::vec4))); // fourth column glEnableVertexAttribArray(5); glVertexAttribPointer(5, 4, GL_FLOAT, GL_FALSE, sizeof(glm::mat4), (void*)(3 * sizeof(glm::vec4))); glVertexAttribDivisor(2, 1); glVertexAttribDivisor(3, 1); glVertexAttribDivisor(4, 1); glVertexAttribDivisor(5, 1); } // ----------- Render Loop ---------- void display(){ int display_w, display_h; glfwGetFramebufferSize(frameWindow->getWindow(), &display_w, &display_h); // Rendering objs Loop ClearAllBufferColor(); glBindVertexArray(VAO); shader.use(); glDrawElementsInstanced(GL_TRIANGLES,6, GL_UNSIGNED_INT, nullptr, INSTANCE_COUNT); // 6 is our indices num //glDrawElements(GL_TRIANGLES,6,GL_UNSIGNED_INT, 0); } int main() { glfwInit(); frameWindow = new FrameWindow(SRC_WIDTH,SRC_HEIGHT); glfwSetFramebufferSizeCallback(frameWindow->getWindow(), framebuffer_size_callback); glfwSetCursorPosCallback(frameWindow->getWindow(),mouse_callback); glfwSetScrollCallback(frameWindow->getWindow(), scroll_callback); init(); //double lastTime = glfwGetTime(); //double targetFps = 60.0f; FPSLimit fpsLimit; fpsLimit.targetFps = 60.02f; FPSGet fpsGet; //double previousTime = glfwGetTime(); //double frameCount = 0; // RENDER-------------- // draw as wireframe //glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); while(!glfwWindowShouldClose(frameWindow->getWindow())){ processInput(frameWindow->getWindow()); fpsLimit.limitFPS(); fpsGet.updateFPS(frameWindow->getWindow()); display(); // Rendering objs Loop int display_w, display_h; glfwGetFramebufferSize(frameWindow->getWindow(), &display_w, &display_h); glViewport(0, 0, display_w, display_h); glfwSwapBuffers(frameWindow->getWindow()); glfwPollEvents(); } delete camera; return 0; } void framebuffer_size_callback(GLFWwindow* window, int width, int height) { // make sure the viewport matches the new window dimensions; note that width and // height will be significantly larger than specified on retina displays. glViewport(0, 0, width, height); } void processInput(GLFWwindow *window) { if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS) glfwSetWindowShouldClose(window, true); if (glfwGetKey(window, GLFW_KEY_W) == GLFW_PRESS) camera->processKeyboardMove(deltaTime,GLFWCamera::FORWARD); if (glfwGetKey(window, GLFW_KEY_S) == GLFW_PRESS) camera->processKeyboardMove(deltaTime,GLFWCamera::BACKWARD); if (glfwGetKey(window, GLFW_KEY_A) == GLFW_PRESS) camera->processKeyboardMove(deltaTime,GLFWCamera::LEFT); if (glfwGetKey(window, GLFW_KEY_D) == GLFW_PRESS) camera->processKeyboardMove(deltaTime,GLFWCamera::RIGHT); } // ROTATE VIEW DIR void mouse_callback(GLFWwindow* window, double xpos, double ypos){ int middow_mouse_state = glfwGetMouseButton(window,GLFW_MOUSE_BUTTON_MIDDLE); int mouse_state = glfwGetMouseButton(window,GLFW_MOUSE_BUTTON_LEFT); int key_state = glfwGetKey(window,GLFW_KEY_LEFT_ALT); // set up the camera view if( mouse_state == GLFW_PRESS && key_state== GLFW_PRESS) { if (firstMouse){ lastX = xpos; lastY = ypos; firstMouse = false; } float xoffset = xpos - lastX; float yoffset = lastY - ypos; // reversed since y-coordinates go from bottom to top lastX = xpos; lastY = ypos; camera->processMouseMove(xoffset,yoffset); } if (key_state == GLFW_RELEASE || mouse_state == GLFW_RELEASE){ firstMouse = true; } // Move Camera Position if( middow_mouse_state == GLFW_PRESS) { if (firstMiddowMouse){ lastX = xpos; lastY = ypos; firstMiddowMouse = false; } float xoffset = xpos - lastX; float yoffset = lastY - ypos; // reversed since y-coordinates go from bottom to top lastX = xpos; lastY = ypos; camera->pos.x += xoffset*0.01f; camera->pos.y += yoffset*0.01f; } if ( middow_mouse_state == GLFW_RELEASE){ firstMiddowMouse = true; } } void scroll_callback(GLFWwindow *window, double xoffset, double yoffset){ camera->processFov(yoffset); }
3,TBO
1,路线就是先创建GL_TEXTURE_BUFFER类型的buffer, 而不是GL_ARRAY_BUFFER,
2,创建纹理
3,然后用glTexBuffer()绑定纹理 到 Buffer上。在GLSL材质中一定是用贴图单元的方式加载。
glCreateBuffers(1,&INST_COLOR_BUFFER); glBindBuffer(GL_TEXTURE_BUFFER,INST_COLOR_BUFFER); glBufferData(GL_TEXTURE_BUFFER, sizeof(glm::vec4)* INSTANCE_COUNT, &colors[0], GL_STATIC_DRAW); glTexBuffer(GL_TEXTURE_BUFFER,GL_RGBA32F,INST_COLOR_BUFFER);
所有的代码:
#define GLEW_STATIC // GLEW #include <GL/glew.h> #include <cstdlib> #undef GLFW_DLL // GLFW #include <GLFW/glfw3.h> #include <iostream> #include "ALG_LoadShader.h" #include "ALG_LoadTexture.h" #include "ALG_GLFWCamera.h" #include "ALG_FrameWindow.h" #include "ALG_ModelDelegate.h" #include "ALG_SceneDelegate.h" #include "ALG_DrawGrid.h" #include "ALG_DrawOriginGnomon.h" #include "ALG_DrawPostPocessingQuad.h" #include "ALG_DrawPlane.h" #include "ALG_DepthShadow.h" #include "ALG_OGLHelper.h" #include "ALG_DirLight.h" #include "ALG_SceneLocation.h" #include <cmath> #include "ALG_Random.h" #include <glm/glm.hpp> #include <glm/gtc/matrix_transform.hpp> #include <glm/gtc/type_ptr.hpp> #include "ALG_FPS.h" using namespace AlgebraMaster; const unsigned int SRC_WIDTH = 900; const unsigned int SRC_HEIGHT = 900; void init(); void display(); void processInput(GLFWwindow *window); void framebuffer_size_callback(GLFWwindow* window, int width, int height); // framezize void mouse_callback(GLFWwindow* window, double xpos, double ypos); // Maya Alt+LeftMouse void scroll_callback(GLFWwindow *window, double xoffset, double yoffset); // camera static GLFWCamera *camera; static float lastX = float(SRC_WIDTH) / 2.0f; static float lastY = float(SRC_HEIGHT) / 2.0f; static bool firstMouse = true; static bool firstMiddowMouse = true; // timing static float deltaTime = 0.0f; // time between current frame and last frame static float lastFrame = 0.0f; static FrameWindow *frameWindow ; // per geometry verticles static float verticles[] = { -0.1f, 0.1f, -0.1f, -0.1f, 0.1f, -0.1f, 0.1f, 0.1f }; static GLuint indices[] = { 0 , 1 , 2, 0 , 2 , 3 }; static GLuint VAO,VBO,EBO; static const int INSTANCE_COUNT = 300; static GLuint INST_COLOR_TBO, INST_MAT_TBO; static GLuint INST_COLOR_BUFFER, INST_MAT_BUFFER; static LoadShader shader; void init(){ glViewport(0,0,SRC_WIDTH,SRC_HEIGHT); if(!CheckExtension("GL_ARB_shading_language_include")){ cout << "---------------ERROR:: SHADER DO NOT SUPPORT INCLUDE SHADER---------------------------------- "; } AddCommonShaderFile("shaders/common/material_interface.glsl"); AddCommonShaderFile("shaders/common/light_interface.glsl"); AddCommonShaderFile("shaders/common/shadow.glsl"); AddCommonShaderFile("shaders/common/utils.glsl"); AddCommonShaderFile("shaders/common/postprocess.glsl"); shader.load("shaders/advanced_instance/part2/surface.vert","shaders/advanced_instance/part2/surface.frag"); camera = new GLFWCamera; camera->pos.y = 0.5f; camera->pos.z = 2.0f; // Create VAO glCreateVertexArrays(1,&VAO); glBindVertexArray(VAO); // set vertex buffer object data glCreateBuffers(1,&VBO); glBindBuffer(GL_ARRAY_BUFFER, VBO); glBufferData(GL_ARRAY_BUFFER,sizeof(verticles),verticles,GL_STATIC_DRAW ); // local position glEnableVertexAttribArray(0); glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, (void*)0); // stride = 0 , offset = void* 0 // create element buffer object glCreateBuffers(1,&EBO); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO); glBufferData(GL_ELEMENT_ARRAY_BUFFER,sizeof(indices), indices, GL_STATIC_DRAW); // -----------create color [-1,1] , but in this default buffer not support HDR , just ignore it----------------------- //glGenTextures(1, &INST_COLOR_TBO); glCreateTextures(GL_TEXTURE_BUFFER , 1 , &INST_COLOR_TBO); glBindTexture(GL_TEXTURE_BUFFER, INST_COLOR_TBO); glm::vec4 colors[INSTANCE_COUNT]; // construct instance color data RandomN1P1 r(INSTANCE_COUNT, 1321); RandomN1P1 g(INSTANCE_COUNT, 321321); RandomN1P1 b(INSTANCE_COUNT,231); //glm::vec3 *colors = new glm::vec3[INSTANCE_COUNT]; for(int i=0;i<INSTANCE_COUNT;i++){ colors[i] = glm::vec4(r[i],g[i],b[i],1); } glCreateBuffers(1,&INST_COLOR_BUFFER); glBindBuffer(GL_TEXTURE_BUFFER,INST_COLOR_BUFFER); glBufferData(GL_TEXTURE_BUFFER, sizeof(glm::vec4)* INSTANCE_COUNT, &colors[0], GL_STATIC_DRAW); glTexBuffer(GL_TEXTURE_BUFFER,GL_RGBA32F,INST_COLOR_BUFFER); // -------------------- Matrix Buffer with a texture ---------------------------- glGenTextures(1,&INST_MAT_TBO); glBindTexture(GL_TEXTURE_BUFFER, INST_MAT_TBO); glm::mat4 mats[INSTANCE_COUNT]; // generator [-1,1] range RandomN1P1 xPosSet(INSTANCE_COUNT, 2312); RandomN1P1 yPosSet(INSTANCE_COUNT, 42); RandomN1P1 zPosSet(INSTANCE_COUNT, 31513); RandomN1P1 rotAmount(INSTANCE_COUNT,523); Random01 scaleAmount(INSTANCE_COUNT,3213); for(int i=0;i<INSTANCE_COUNT;i++){ // new translate glm::mat4 model(1.0f); model = glm::translate(model,glm::vec3(xPosSet[i], yPosSet[i], zPosSet[i] ) ); // new rot glm::mat4 rot(1.0f); rot = glm::rotate(rot,glm::radians(rotAmount[i]*360) , glm::vec3(0.0,0.0,1.0)); // R S T order glm::mat4 scale(1.0f); scale = glm::scale( scale,glm::vec3(scaleAmount[i]) ); mats[i] = model * scale * rot ; } glCreateBuffers(1,&INST_MAT_BUFFER); glBindBuffer(GL_TEXTURE_BUFFER,INST_MAT_BUFFER); glBufferData(GL_TEXTURE_BUFFER,sizeof(glm::mat4) * INSTANCE_COUNT, &mats[0],GL_STATIC_DRAW); glTexBuffer(GL_TEXTURE_BUFFER,GL_RGBA32F,INST_MAT_BUFFER); glActiveTexture(GL_TEXTURE0); shader.use(); shader.setInt("color_tbo",0); shader.setInt("model_matrix_tbo",1); } // ----------- Render Loop ---------- void display(){ int display_w, display_h; glfwGetFramebufferSize(frameWindow->getWindow(), &display_w, &display_h); // Rendering objs Loop ClearAllBufferColor(); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_BUFFER, INST_COLOR_TBO); glActiveTexture(GL_TEXTURE1); glBindTexture(GL_TEXTURE_BUFFER, INST_MAT_TBO); shader.use(); glBindVertexArray(VAO); glDrawElementsInstanced(GL_TRIANGLES,6, GL_UNSIGNED_INT, nullptr, INSTANCE_COUNT); // 6 is our indices num //glDrawElements(GL_TRIANGLES,6,GL_UNSIGNED_INT, 0); } int main() { glfwInit(); frameWindow = new FrameWindow(SRC_WIDTH,SRC_HEIGHT); glfwSetFramebufferSizeCallback(frameWindow->getWindow(), framebuffer_size_callback); glfwSetCursorPosCallback(frameWindow->getWindow(),mouse_callback); glfwSetScrollCallback(frameWindow->getWindow(), scroll_callback); init(); //double lastTime = glfwGetTime(); //double targetFps = 60.0f; FPSLimit fpsLimit; fpsLimit.targetFps = 60.02f; FPSGet fpsGet; //double previousTime = glfwGetTime(); //double frameCount = 0; // RENDER-------------- // draw as wireframe //glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); while(!glfwWindowShouldClose(frameWindow->getWindow())){ processInput(frameWindow->getWindow()); fpsLimit.limitFPS(); fpsGet.updateFPS(frameWindow->getWindow()); display(); // Rendering objs Loop int display_w, display_h; glfwGetFramebufferSize(frameWindow->getWindow(), &display_w, &display_h); glViewport(0, 0, display_w, display_h); glfwSwapBuffers(frameWindow->getWindow()); glfwPollEvents(); } delete camera; return 0; } void framebuffer_size_callback(GLFWwindow* window, int width, int height) { // make sure the viewport matches the new window dimensions; note that width and // height will be significantly larger than specified on retina displays. glViewport(0, 0, width, height); } void processInput(GLFWwindow *window) { if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS) glfwSetWindowShouldClose(window, true); if (glfwGetKey(window, GLFW_KEY_W) == GLFW_PRESS) camera->processKeyboardMove(deltaTime,GLFWCamera::FORWARD); if (glfwGetKey(window, GLFW_KEY_S) == GLFW_PRESS) camera->processKeyboardMove(deltaTime,GLFWCamera::BACKWARD); if (glfwGetKey(window, GLFW_KEY_A) == GLFW_PRESS) camera->processKeyboardMove(deltaTime,GLFWCamera::LEFT); if (glfwGetKey(window, GLFW_KEY_D) == GLFW_PRESS) camera->processKeyboardMove(deltaTime,GLFWCamera::RIGHT); } // ROTATE VIEW DIR void mouse_callback(GLFWwindow* window, double xpos, double ypos){ int middow_mouse_state = glfwGetMouseButton(window,GLFW_MOUSE_BUTTON_MIDDLE); int mouse_state = glfwGetMouseButton(window,GLFW_MOUSE_BUTTON_LEFT); int key_state = glfwGetKey(window,GLFW_KEY_LEFT_ALT); // set up the camera view if( mouse_state == GLFW_PRESS && key_state== GLFW_PRESS) { if (firstMouse){ lastX = xpos; lastY = ypos; firstMouse = false; } float xoffset = xpos - lastX; float yoffset = lastY - ypos; // reversed since y-coordinates go from bottom to top lastX = xpos; lastY = ypos; camera->processMouseMove(xoffset,yoffset); } if (key_state == GLFW_RELEASE || mouse_state == GLFW_RELEASE){ firstMouse = true; } // Move Camera Position if( middow_mouse_state == GLFW_PRESS) { if (firstMiddowMouse){ lastX = xpos; lastY = ypos; firstMiddowMouse = false; } float xoffset = xpos - lastX; float yoffset = lastY - ypos; // reversed since y-coordinates go from bottom to top lastX = xpos; lastY = ypos; camera->pos.x += xoffset*0.01f; camera->pos.y += yoffset*0.01f; } if ( middow_mouse_state == GLFW_RELEASE){ firstMiddowMouse = true; } } void scroll_callback(GLFWwindow *window, double xoffset, double yoffset){ camera->processFov(yoffset); }
#version 450 core layout ( location = 0 ) in vec2 vPosition; // c++ pos uniform samplerBuffer color_tbo; uniform samplerBuffer model_matrix_tbo; out VERTEX{ vec3 color; }vertex; void main(){ // instance color vec4 inst_color = texelFetch(color_tbo, gl_InstanceID); //vec4 inst_color = vec4(1.0,0.0,0,1); // get instance matrix column vec4 col1 = texelFetch(model_matrix_tbo, gl_InstanceID * 4); vec4 col2 = texelFetch(model_matrix_tbo, gl_InstanceID * 4 + 1); vec4 col3 = texelFetch(model_matrix_tbo, gl_InstanceID * 4 + 2); vec4 col4 = texelFetch(model_matrix_tbo, gl_InstanceID * 4 + 3); mat4 model_matrix = mat4(col1,col2,col3,col4); gl_Position = model_matrix * vec4(vPosition.x, vPosition.y, 0.0, 1.0); vertex.color = inst_color.rgb; }
3, TBO with glMapBuffer()
只修改了mat方法,同样按照这个逻辑用于修改colors
#define GLEW_STATIC // GLEW #include <GL/glew.h> #include <cstdlib> #undef GLFW_DLL // GLFW #include <GLFW/glfw3.h> #include <iostream> #include "ALG_LoadShader.h" #include "ALG_LoadTexture.h" #include "ALG_GLFWCamera.h" #include "ALG_FrameWindow.h" #include "ALG_ModelDelegate.h" #include "ALG_SceneDelegate.h" #include "ALG_DrawGrid.h" #include "ALG_DrawOriginGnomon.h" #include "ALG_DrawPostPocessingQuad.h" #include "ALG_DrawPlane.h" #include "ALG_DepthShadow.h" #include "ALG_OGLHelper.h" #include "ALG_DirLight.h" #include "ALG_SceneLocation.h" #include <cmath> #include "ALG_Random.h" #include <glm/glm.hpp> #include <glm/gtc/matrix_transform.hpp> #include <glm/gtc/type_ptr.hpp> #include "ALG_FPS.h" using namespace AlgebraMaster; const unsigned int SRC_WIDTH = 900; const unsigned int SRC_HEIGHT = 900; void init(); void display(); void processInput(GLFWwindow *window); void framebuffer_size_callback(GLFWwindow* window, int width, int height); // framezize void mouse_callback(GLFWwindow* window, double xpos, double ypos); // Maya Alt+LeftMouse void scroll_callback(GLFWwindow *window, double xoffset, double yoffset); // camera static GLFWCamera *camera; static float lastX = float(SRC_WIDTH) / 2.0f; static float lastY = float(SRC_HEIGHT) / 2.0f; static bool firstMouse = true; static bool firstMiddowMouse = true; // timing static float deltaTime = 0.0f; // time between current frame and last frame static float lastFrame = 0.0f; static FrameWindow *frameWindow ; // per geometry verticles static float verticles[] = { -0.1f, 0.1f, -0.1f, -0.1f, 0.1f, -0.1f, 0.1f, 0.1f }; static GLuint indices[] = { 0 , 1 , 2, 0 , 2 , 3 }; static GLuint VAO,VBO,EBO; static const int INSTANCE_COUNT = 300; static GLuint INST_COLOR_TBO, INST_MAT_TBO; static GLuint INST_COLOR_BUFFER, INST_MAT_BUFFER; static LoadShader shader; void init(){ glViewport(0,0,SRC_WIDTH,SRC_HEIGHT); if(!CheckExtension("GL_ARB_shading_language_include")){ cout << "---------------ERROR:: SHADER DO NOT SUPPORT INCLUDE SHADER---------------------------------- "; } AddCommonShaderFile("shaders/common/material_interface.glsl"); AddCommonShaderFile("shaders/common/light_interface.glsl"); AddCommonShaderFile("shaders/common/shadow.glsl"); AddCommonShaderFile("shaders/common/utils.glsl"); AddCommonShaderFile("shaders/common/postprocess.glsl"); shader.load("shaders/advanced_instance/part2/surface.vert","shaders/advanced_instance/part2/surface.frag"); camera = new GLFWCamera; camera->pos.y = 0.5f; camera->pos.z = 2.0f; // Create VAO glCreateVertexArrays(1,&VAO); glBindVertexArray(VAO); // set vertex buffer object data glCreateBuffers(1,&VBO); glBindBuffer(GL_ARRAY_BUFFER, VBO); glBufferData(GL_ARRAY_BUFFER,sizeof(verticles),verticles,GL_STATIC_DRAW ); // local position glEnableVertexAttribArray(0); glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, (void*)0); // stride = 0 , offset = void* 0 // create element buffer object glCreateBuffers(1,&EBO); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO); glBufferData(GL_ELEMENT_ARRAY_BUFFER,sizeof(indices), indices, GL_STATIC_DRAW); // -----------create color [-1,1] , but in this default buffer not support HDR , just ignore it----------------------- //glGenTextures(1, &INST_COLOR_TBO); glCreateTextures(GL_TEXTURE_BUFFER , 1 , &INST_COLOR_TBO); glBindTexture(GL_TEXTURE_BUFFER, INST_COLOR_TBO); glm::vec4 colors[INSTANCE_COUNT]; // construct instance color data RandomN1P1 r(INSTANCE_COUNT, 1321); RandomN1P1 g(INSTANCE_COUNT, 321321); RandomN1P1 b(INSTANCE_COUNT,231); //glm::vec3 *colors = new glm::vec3[INSTANCE_COUNT]; for(int i=0;i<INSTANCE_COUNT;i++){ colors[i] = glm::vec4(r[i],g[i],b[i],1); } glCreateBuffers(1,&INST_COLOR_BUFFER); glBindBuffer(GL_TEXTURE_BUFFER,INST_COLOR_BUFFER); glBufferData(GL_TEXTURE_BUFFER, sizeof(glm::vec4)* INSTANCE_COUNT, &colors[0], GL_STATIC_DRAW); glTexBuffer(GL_TEXTURE_BUFFER,GL_RGBA32F,INST_COLOR_BUFFER); // -------------------- Matrix Buffer with a texture ---------------------------- glGenTextures(1,&INST_MAT_TBO); glBindTexture(GL_TEXTURE_BUFFER, INST_MAT_TBO); glCreateBuffers(1,&INST_MAT_BUFFER); glBindBuffer(GL_TEXTURE_BUFFER,INST_MAT_BUFFER); glBufferData(GL_TEXTURE_BUFFER,sizeof(glm::mat4) * INSTANCE_COUNT, nullptr,GL_STATIC_DRAW); glm::mat4 *mats = (glm::mat4*)glMapBuffer(GL_TEXTURE_BUFFER, GL_WRITE_ONLY); // generator [-1,1] range RandomN1P1 xPosSet(INSTANCE_COUNT, 2312); RandomN1P1 yPosSet(INSTANCE_COUNT, 42); RandomN1P1 zPosSet(INSTANCE_COUNT, 31513); RandomN1P1 rotAmount(INSTANCE_COUNT,523); Random01 scaleAmount(INSTANCE_COUNT,3213); for(int i=0;i<INSTANCE_COUNT;i++){ // new translate glm::mat4 model(1.0f); model = glm::translate(model,glm::vec3(xPosSet[i], yPosSet[i], zPosSet[i] ) ); // new rot glm::mat4 rot(1.0f); rot = glm::rotate(rot,glm::radians(rotAmount[i]*360) , glm::vec3(0.0,0.0,1.0)); // R S T order glm::mat4 scale(1.0f); scale = glm::scale( scale,glm::vec3(scaleAmount[i]) ); mats[i] = model * scale * rot ; } glUnmapBuffer(GL_TEXTURE_BUFFER); glTexBuffer(GL_TEXTURE_BUFFER,GL_RGBA32F,INST_MAT_BUFFER); glActiveTexture(GL_TEXTURE0); shader.use(); shader.setInt("color_tbo",0); shader.setInt("model_matrix_tbo",1); } // ----------- Render Loop ---------- void display(){ int display_w, display_h; glfwGetFramebufferSize(frameWindow->getWindow(), &display_w, &display_h); // Rendering objs Loop ClearAllBufferColor(); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_BUFFER, INST_COLOR_TBO); glActiveTexture(GL_TEXTURE1); glBindTexture(GL_TEXTURE_BUFFER, INST_MAT_TBO); shader.use(); glBindVertexArray(VAO); glDrawElementsInstanced(GL_TRIANGLES,6, GL_UNSIGNED_INT, nullptr, INSTANCE_COUNT); // 6 is our indices num //glDrawElements(GL_TRIANGLES,6,GL_UNSIGNED_INT, 0); } int main() { glfwInit(); frameWindow = new FrameWindow(SRC_WIDTH,SRC_HEIGHT); glfwSetFramebufferSizeCallback(frameWindow->getWindow(), framebuffer_size_callback); glfwSetCursorPosCallback(frameWindow->getWindow(),mouse_callback); glfwSetScrollCallback(frameWindow->getWindow(), scroll_callback); init(); //double lastTime = glfwGetTime(); //double targetFps = 60.0f; FPSLimit fpsLimit; fpsLimit.targetFps = 60.02f; FPSGet fpsGet; //double previousTime = glfwGetTime(); //double frameCount = 0; // RENDER-------------- // draw as wireframe //glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); while(!glfwWindowShouldClose(frameWindow->getWindow())){ processInput(frameWindow->getWindow()); fpsLimit.limitFPS(); fpsGet.updateFPS(frameWindow->getWindow()); display(); // Rendering objs Loop int display_w, display_h; glfwGetFramebufferSize(frameWindow->getWindow(), &display_w, &display_h); glViewport(0, 0, display_w, display_h); glfwSwapBuffers(frameWindow->getWindow()); glfwPollEvents(); } delete camera; return 0; } void framebuffer_size_callback(GLFWwindow* window, int width, int height) { // make sure the viewport matches the new window dimensions; note that width and // height will be significantly larger than specified on retina displays. glViewport(0, 0, width, height); } void processInput(GLFWwindow *window) { if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS) glfwSetWindowShouldClose(window, true); if (glfwGetKey(window, GLFW_KEY_W) == GLFW_PRESS) camera->processKeyboardMove(deltaTime,GLFWCamera::FORWARD); if (glfwGetKey(window, GLFW_KEY_S) == GLFW_PRESS) camera->processKeyboardMove(deltaTime,GLFWCamera::BACKWARD); if (glfwGetKey(window, GLFW_KEY_A) == GLFW_PRESS) camera->processKeyboardMove(deltaTime,GLFWCamera::LEFT); if (glfwGetKey(window, GLFW_KEY_D) == GLFW_PRESS) camera->processKeyboardMove(deltaTime,GLFWCamera::RIGHT); } // ROTATE VIEW DIR void mouse_callback(GLFWwindow* window, double xpos, double ypos){ int middow_mouse_state = glfwGetMouseButton(window,GLFW_MOUSE_BUTTON_MIDDLE); int mouse_state = glfwGetMouseButton(window,GLFW_MOUSE_BUTTON_LEFT); int key_state = glfwGetKey(window,GLFW_KEY_LEFT_ALT); // set up the camera view if( mouse_state == GLFW_PRESS && key_state== GLFW_PRESS) { if (firstMouse){ lastX = xpos; lastY = ypos; firstMouse = false; } float xoffset = xpos - lastX; float yoffset = lastY - ypos; // reversed since y-coordinates go from bottom to top lastX = xpos; lastY = ypos; camera->processMouseMove(xoffset,yoffset); } if (key_state == GLFW_RELEASE || mouse_state == GLFW_RELEASE){ firstMouse = true; } // Move Camera Position if( middow_mouse_state == GLFW_PRESS) { if (firstMiddowMouse){ lastX = xpos; lastY = ypos; firstMiddowMouse = false; } float xoffset = xpos - lastX; float yoffset = lastY - ypos; // reversed since y-coordinates go from bottom to top lastX = xpos; lastY = ypos; camera->pos.x += xoffset*0.01f; camera->pos.y += yoffset*0.01f; } if ( middow_mouse_state == GLFW_RELEASE){ firstMiddowMouse = true; } } void scroll_callback(GLFWwindow *window, double xoffset, double yoffset){ camera->processFov(yoffset); }