OpenGL + Uniform Variables没有到达着色器+样条线

时间:2016-02-06 22:20:49

标签: c++ opengl

我有一个非常奇怪的问题,我无法弄清楚。对于我的场景,我创建了一个样条曲线类,用于生成我的相机遍历的点。当我在场景中创建样条线类的实例并使用它时,这可以正常工作。我在样条曲线类中有一些功能,用于显示样条曲线上的点,这些点使用统一数据绘制它们的位置并为它们提供颜色。当我在场景中直接创建实例时,这一切都正常。

但是,我想创建多个样条线来让我的相机遍历,所以我创建了一个相当简单的管理类来处理多个样条线。然而,由于某些原因,我无法解释为什么当我使用管理器创建样条曲线的实例时,统一变量不起作用。其他一切都很好。当我说他们不工作我的意思是getLocation函数工作(他们按预期获得locationID),要发送的数据是相同的,没有关于应该的函数的错误或警告实际上将数据发送到他们的位置。样条曲线正确绘制,但它们总是黑色并且没有被翻译过。

这是我的场景课。我的经理和样条曲线类的构造函数完全相同,所以在我的ClothScene.hpp中我可以将mSplineManager对象的类型从manager类切换到样条线类,并且统一变量可以正常工作。

#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 up and 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 back and 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);
        }

    }
}

这是我的SplineManger课程。它非常简单,它只是创建一个样条线矢量,然后应用迭代通过矢量中所有样条线的完全相同的功能。由于某种原因,这会阻止着色器接收统一数据。

#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) {
    for (int i = 0; i < 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() {
    for (int i = 0; i < mSplines.size(); ++i) {
        mSplines[i].showSpline();
    }

}
void SplineManager::showControlPoints() {
    for (int i = 0; i < mSplines.size(); ++i) {
        mSplines[i].showControlPoints();
    }
}
void SplineManager::showCage() {
    for (int i = 0; i < mSplines.size(); ++i) {
        mSplines[i].showCage();
    }
}
void SplineManager::showSplinePoints() {
    for (int i = 0; i < mSplines.size(); ++i) {
        mSplines[i].showSplinePoints();
    }
}
bool SplineManager::doneInterpolation() {
    return finishedAllSplines;
}

这是我的样条曲线类。再次,当我在场景类中直接创建它的实例时,这一切都完全正常。在SplineManager中创建实例时,统一变量不起作用。

#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;
    for (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 the 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()));
    }

    // Now draw the 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);

    for (int i = 1; i < 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 the entry in our table that corresponds to the given distance.
    float epsilon = chooseEpsilon();
    for (int i = 0; i < int(mTable.size()); ++i)
    {
        if (glm::abs(mTable[i] - distance) < epsilon)
        {
            return i;
        }
    }

    return -1;
}

float Spline::chooseEpsilon()
{
    // Find the largest difference and use that to look up distances
    // in our table.
    float epsilon = 0.0f;
    float diff;
    for (int i = 0; i < 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_;
} 

任何感兴趣的人的头文件。

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

0 个答案:

没有答案