c++ - OpenGL + Uniform Variables not reaching shaders + splines -
i have peculiar problem can not figure out. scene have created spline class use generate points camera traverses. works fine , dandy when create instance of spline class in scene , use it. have functionality in spline class showing points on spline use uniform data draw position , give them color. works fine when create instance directly in scene.
however, want create multiple splines have camera traverse created simple management class handle multiple splines. works reason can not puzzle out why when create instance of spline manager uniform variables aren't working. else works fine. when don't work mean getlocation functions work (they locationids expected), data sent same, there no errors or warnings concerning functions supposed send data down locations. spline draws black , haven't been translated.
here scene class. constructors both manager , spline class self same in clothscene.hpp can switch type of msplinemanager object manager class spline class , uniform variables work fine.
#include "clothscene.hpp" #include <atlas/core/glfw.hpp> #include <atlas/core/log.hpp> #include <atlas/core/macros.hpp> #include <atlas/core/float.hpp> #include <iostream> clothscene::clothscene() : misplaying(false), mlasttime(0.0f), mfps(60.0f), mtick(1.0f / mfps), manimtime(0.0f), manimlength(10.0f), msplinemanager(int(manimlength * mfps)), ballposition{ -10.0f, 0.0f, 14.0f } { glenable(gl_depth_test); auto mat = glm::translate(atlas::math::matrix4(1.0f), ballposition); mball.transformgeometry(mat); } clothscene::~clothscene() { } void clothscene::mousepressevent(int button, int action, int modifiers, double xpos, double ypos) { using_atlas_math_ns; if (button == glfw_mouse_button_left && modifiers == glfw_mod_alt) { if (action == glfw_press) { misdragging = true; //camera tilt , down or turn left, right mcamera.mousedown(point2(xpos, ypos), clothcamera::cameramovements::tumble); } else { misdragging = false; mcamera.mouseup(); } } else if (button == glfw_mouse_button_middle && modifiers == glfw_mod_alt) { if (action == glfw_press) { misdragging = true; //camera move left, right, up, down mcamera.mousedown(point2(xpos, ypos), clothcamera::cameramovements::track); } else { misdragging = false; mcamera.mouseup(); } } else if (button == glfw_mouse_button_right && modifiers == glfw_mod_alt) { if (action == glfw_press) { // first click. misdragging = true; //camera move , forth mcamera.mousedown(point2(xpos, ypos), clothcamera::cameramovements::dolly); } else { misdragging = false; mcamera.mouseup(); } } else if (action != glfw_press) { misdragging = false; mcamera.mouseup(); } } void clothscene::mousemoveevent(double xpos, double ypos) { mcamera.mouseupdate(glm::vec2(xpos, ypos)); } void clothscene::keypressevent(int key, int scancode, int action, int mods) { unused(scancode); unused(mods); if (action == glfw_press) { switch (key) { case glfw_key_t: mcamera.resetcamera(); break; case glfw_key_w: mcamera.strafecamera(0); break; case glfw_key_s: mcamera.strafecamera(1); break; case glfw_key_a: mcamera.strafecamera(2); break; case glfw_key_d: mcamera.strafecamera(3); break; case glfw_key_r: mcamera.strafecamera(4); break; case glfw_key_f: mcamera.strafecamera(5); break; case glfw_key_q: mcamera.strafecamera(6); break; case glfw_key_e: mcamera.strafecamera(7); break; case glfw_key_c: mcamera.newposition(glm::vec3(0.0f, 3.0f, 0.0f)); break; case glfw_key_u: msplinemanager.showspline(); break; case glfw_key_i: msplinemanager.showcontrolpoints(); break; case glfw_key_o: msplinemanager.showcage(); break; case glfw_key_p: msplinemanager.showsplinepoints(); break; case glfw_key_space: misplaying = !misplaying; default: break; } } } void clothscene::screenresizeevent(int width, int height) { glviewport(0, 0, width, height); mprojection = glm::perspective(glm::radians(45.0),(double)width / height, 1.0, 1000.0); } void clothscene::renderscene() { float grey = 161.0f / 255.0f; glclearcolor(grey, grey, grey, 1.0f); glclear(gl_color_buffer_bit | gl_depth_buffer_bit); glenable(gl_depth_test); mview = mcamera.getcameramatrix(); mgrid.rendergeometry(mprojection, mview); msplinemanager.rendergeometry(mprojection, mview); mball.rendergeometry(mprojection, mview); } void clothscene::updatescene(double time) { mtime.currenttime = (float)time; mtime.totaltime += (float)time; if (atlas::core::geq(mtime.currenttime - mlasttime, mtick)) { mlasttime += mtick; mtime.deltatime = mtick; if (misplaying) { manimtime += mtick; msplinemanager.updategeometry(mtime); if (msplinemanager.doneinterpolation()) { misplaying = false; return; } auto point = msplinemanager.getsplineposition(); mcamera.newposition(point); mcamera.lookat(ballposition); auto mat = glm::translate(atlas::math::matrix4(1.0f), ballposition); mball.transformgeometry(mat); } } } here splinemanger class. super simple, creates vector of splines , applies exact same functionality iterated through of splines in vector. reason prevents shader receiving uniform data.
#include "splinemanager.hpp" splinemanager::splinemanager(int totalframes) : finishedallsplines(false), currentspline(0) { mtotalframes = totalframes; addsplines(); } splinemanager::~splinemanager() { } void splinemanager::addsplines() { mcontrolpoints = std::vector<point> { { -20, -5, 0 }, { -19, 5, -15 }, { 12.7f, -5, -1.4f }, { 20, 8.2f, 4.4f } }; msplines.push_back(spline(mtotalframes, mcontrolpoints)); } void splinemanager::rendergeometry(atlas::math::matrix4 projection, atlas::math::matrix4 view) { (int = 0; < msplines.size(); ++i) { msplines[i].rendergeometry(projection, view); } } void splinemanager::updategeometry(atlas::utils::time const& t) { msplines[currentspline].updategeometry(t); if (msplines[currentspline].doneinterpolation()) { ++currentspline; if (currentspline == msplines.size()) { finishedallsplines = true; } } } atlas::math::point splinemanager::getsplineposition() { return msplines[currentspline].getsplineposition(); } void splinemanager::showspline() { (int = 0; < msplines.size(); ++i) { msplines[i].showspline(); } } void splinemanager::showcontrolpoints() { (int = 0; < msplines.size(); ++i) { msplines[i].showcontrolpoints(); } } void splinemanager::showcage() { (int = 0; < msplines.size(); ++i) { msplines[i].showcage(); } } void splinemanager::showsplinepoints() { (int = 0; < msplines.size(); ++i) { msplines[i].showsplinepoints(); } } bool splinemanager::doneinterpolation() { return finishedallsplines; } here spline class. again, works totally fine when directly create instance of in scene class. when instances created in splinemanager uniform variables don't work.
#include "spline.h" #include "shaderpaths.hpp" #include <atlas/core/macros.hpp> spline::spline(int totalframes) : mresolution(500), mtotalframes(totalframes), mcurrentframe(0), mshowcontrolpoints(false), mshowcage(false), mshowsplinepoints(false), mshowspline(false), misinterpolationdone(false) { using_atlas_math_ns; using_atlas_gl_ns; //bezier mbasismatrix = matrix4( 1.0f, 0.0f, 0.0f, 0.0f, -3.0f, 3.0f, 0.0f, 0.0f, 3.0f, -6.0f, 3.0f, 0.0f, -1.0f, 3.0f, -3.0f, 1.0f); mcontrolpoints = std::vector<point> { { -20, -5, 0 }, { -19, 5, -15 }, { 12.7f, -5, -1.4f }, { 20, 8.2f, 4.4f } }; std::vector<point> splinepoints; float scale = 1.0f / mresolution; (int res = 0; res < mresolution + 1; ++res) { splinepoints.push_back(evaluatespline(scale * res)); } generatearclengthtable(); glgenvertexarrays(1, &mvao); glbindvertexarray(mvao); glgenbuffers(1, &mcontrolbuffer); glbindbuffer(gl_array_buffer, mcontrolbuffer); glbufferdata(gl_array_buffer, sizeof(point) * mcontrolpoints.size(), mcontrolpoints.data(), gl_static_draw); glgenbuffers(1, &msplinebuffer); glbindbuffer(gl_array_buffer, msplinebuffer); glbufferdata(gl_array_buffer, sizeof(point) * splinepoints.size(), splinepoints.data(), gl_static_draw); std::string shaderdir = generated::shaderpaths::getshaderdirectory(); std::vector<shaderinfo> shaders { { gl_vertex_shader, shaderdir + "spline.vs.glsl" }, { gl_fragment_shader, shaderdir + "spline.fs.glsl" } }; mshaders.push_back(shaderpointer(new shader)); mshaders[0]->compileshaders(shaders); mshaders[0]->linkshaders(); gluint var; var = mshaders[0]->getuniformvariable("umvp"); muniforms.insert(uniformkey("umvp", var)); var = mshaders[0]->getuniformvariable("fcolour"); muniforms.insert(uniformkey("fcolour", var)); mshaders[0]->disableshaders(); glbindvertexarray(0); } spline::~spline() { gldeletevertexarrays(1, &mvao); gldeletevertexarrays(1, &mcontrolbuffer); gldeletevertexarrays(1, &msplinebuffer); } void spline::rendergeometry(atlas::math::matrix4 projection, atlas::math::matrix4 view) { using_atlas_math_ns; mshaders[0]->enableshaders(); glbindvertexarray(mvao); matrix4 mvp = projection * view * mmodel; gluniformmatrix4fv(muniforms["umvp"], 1, gl_false, &mvp[0][0]); // draw control points first. gluniform3f(muniforms["fcolour"], 1, 0, 0); glenablevertexattribarray(0); glbindbuffer(gl_array_buffer, mcontrolbuffer); glvertexattribpointer(0, 3, gl_float, gl_false, 0, (void*)0); if (mshowcontrolpoints) { glpointsize(5.0f); gldrawarrays(gl_points, 0, glsizei(mcontrolpoints.size())); glpointsize(1.0f); } if (mshowcage) { gldrawarrays(gl_line_strip, 0, glsizei(mcontrolpoints.size())); } // draw spline. glenablevertexattribarray(0); glbindbuffer(gl_array_buffer, msplinebuffer); glvertexattribpointer(0, 3, gl_float, gl_false, 0, (void*)0); gluniform3f(muniforms["fcolour"], 0, 1, 0); if (mshowspline) { gllinewidth(5.0f); gldrawarrays(gl_line_strip, 0, mresolution + 1); gllinewidth(1.0f); } if (mshowsplinepoints) { glpointsize(8.0f); gldrawarrays(gl_points, 1, mresolution); glpointsize(1.0f); } gldisablevertexattribarray(0); mshaders[0]->disableshaders(); } void spline::updategeometry(atlas::utils::time const& t) { unused(t); msplineposition = interpolateonspline(); mcurrentframe++; if (mcurrentframe == mtotalframes) { misinterpolationdone = true; return; } } void spline::showcontrolpoints() { mshowcontrolpoints = !mshowcontrolpoints; } void spline::showcage() { mshowcage = !mshowcage; } void spline::showsplinepoints() { mshowsplinepoints = !mshowsplinepoints; } void spline::showspline() { mshowspline = !mshowspline; } bool spline::doneinterpolation() { return misinterpolationdone; } atlas::math::point spline::getsplineposition() { return msplineposition; } atlas::math::point spline::interpolateonspline() { int n = int(mtable.size()); float totaldistance = mtable[n - 1]; float step = totaldistance / mtotalframes; float currdistance = step * mcurrentframe; int index = tablelookup(currdistance); float t = (1.0f / mresolution) * (index % mresolution); return evaluatespline(t); } atlas::math::point spline::evaluatespline(float t) { using_atlas_math_ns; vector4 xcontrols = { mcontrolpoints[0].x, mcontrolpoints[1].x, mcontrolpoints[2].x, mcontrolpoints[3].x }; vector4 ycontrols = { mcontrolpoints[0].y, mcontrolpoints[1].y, mcontrolpoints[2].y, mcontrolpoints[3].y }; vector4 zcontrols = { mcontrolpoints[0].z, mcontrolpoints[1].z, mcontrolpoints[2].z, mcontrolpoints[3].z }; vector4 xcoeff = xcontrols * mbasismatrix; vector4 ycoeff = ycontrols * mbasismatrix; vector4 zcoeff = zcontrols * mbasismatrix; float xcr, ycr, zcr; xcr = xcoeff[0] + t * xcoeff[1] + t * t * xcoeff[2] + t * t * t * xcoeff[3]; ycr = ycoeff[0] + t * ycoeff[1] + t * t * ycoeff[2] + t * t * t * ycoeff[3]; zcr = zcoeff[0] + t * zcoeff[1] + t * t * zcoeff[2] + t * t * t * zcoeff[3]; return point(xcr, ycr, zcr); } void spline::generatearclengthtable() { using_atlas_math_ns; if (!mtable.empty()) { mtable.clear(); } float scale = 1.0f / mresolution; mtable.push_back(0.0f); (int = 1; < mresolution + 1; ++i) { point p0 = evaluatespline((i - 1) * scale); point p1 = evaluatespline(i * scale); point dist = p0 - p1; mtable.push_back(mtable[i - 1] + glm::length(dist)); } } int spline::tablelookup(float distance) { // find entry in our table corresponds given distance. float epsilon = chooseepsilon(); (int = 0; < int(mtable.size()); ++i) { if (glm::abs(mtable[i] - distance) < epsilon) { return i; } } return -1; } float spline::chooseepsilon() { // find largest difference , use distances // in our table. float epsilon = 0.0f; float diff; (int = 0; < mtable.size() - 1; ++i) { diff = glm::abs(mtable[i] - mtable[i + 1]); if (diff > epsilon) { epsilon = diff; } } return epsilon; } void spline::setsplinecoordinates(std::vector<atlas::math::point> mcontrolpoints_) { mcontrolpoints = mcontrolpoints_; } the header files interested.
splinemanager.hpp
#ifndef splinemanager_hpp #define splinemanager_hpp #pragma once #include <atlas/utils/geometry.hpp> #include "spline.h" using_atlas_math_ns; using_atlas_gl_ns; class splinemanager : public atlas::utils::geometry { public: splinemanager(int totalframes); ~splinemanager(); atlas::math::point getsplineposition(); void addsplines(); void showspline(); void showcontrolpoints(); void showcage(); void showsplinepoints(); bool doneinterpolation(); void updategeometry(atlas::utils::time const& t) override; void rendergeometry(atlas::math::matrix4 projection, atlas::math::matrix4 view) override; private: std::vector<spline> msplines; std::vector<atlas::math::point> mcontrolpoints; int mtotalframes; int currentspline; bool finishedallsplines; }; #endif spline.h
#ifndef lab04_include_spline_hpp #define lab04_include_spline_hpp #pragma once #include <atlas/utils/geometry.hpp> #include <fstream> class spline : public atlas::utils::geometry { public: spline(int totalframes, std::vector<atlas::math::point> mcontrolpoints_); spline(int totalframes); ~spline(); void rendergeometry(atlas::math::matrix4 projection, atlas::math::matrix4 view) override; void updategeometry(atlas::utils::time const& t) override; void showcontrolpoints(); void showcage(); void showsplinepoints(); void showspline(); bool doneinterpolation(); atlas::math::point getsplineposition(); void setsplinecoordinates(std::vector<atlas::math::point> mcontrolpoints_); private: atlas::math::point interpolateonspline(); atlas::math::point evaluatespline(float t); void generatearclengthtable(); int tablelookup(float distance); float chooseepsilon(); atlas::math::matrix4 mbasismatrix; std::vector<atlas::math::point> mcontrolpoints; std::vector<float> mtable; atlas::math::point msplineposition; gluint mvao; gluint mcontrolbuffer; gluint msplinebuffer; int mresolution; int mtotalframes; int mcurrentframe; bool mshowcontrolpoints; bool mshowcage; bool mshowsplinepoints; bool mshowspline; bool misinterpolationdone; }; #endif clothscene.hpp
#ifndef scene_hpp #define scene_hpp #pragma once #include <atlas\utils\scene.hpp> #include "clothcamera.hpp" #include "splinemanager.hpp" #include "grid.hpp" #include "spline.h" #include "ball.hpp" //#include "cloth.hpp" class clothscene : public atlas::utils::scene { public: clothscene(); ~clothscene(); void mousepressevent(int button, int action, int modifiers, double xpos, double ypos) override; void mousemoveevent(double xpos, double ypos) override; void keypressevent(int key, int scancode, int action, int mods) override; void screenresizeevent(int width, int height) override; void renderscene() override; void updatescene(double time) override; private: bool misdragging; bool misplaying; float mlasttime; float mfps; float mtick; float manimtime; float manimlength; glm::vec3 ballposition; clothcamera mcamera; grid mgrid; splinemanager msplinemanager;//, mspline2; ball mball; std::vector<atlas::math::point> mcontrolpoints; }; #endif
Comments
Post a Comment