зеркало из https://github.com/AvaloniaUI/angle.git
Add an instancing perf test.
BUG=526217 BUG=angleproject:1164 Change-Id: Ia353a3b2fa0ab0e8b7fd15d72bb63e5ecb7833b1 Reviewed-on: https://chromium-review.googlesource.com/301469 Reviewed-by: Geoff Lang <geofflang@chromium.org> Tryjob-Request: Jamie Madill <jmadill@chromium.org> Tested-by: Jamie Madill <jmadill@chromium.org>
This commit is contained in:
Родитель
3215b207b2
Коммит
90c253a616
|
@ -14,6 +14,8 @@
|
||||||
#include "random_utils.h"
|
#include "random_utils.h"
|
||||||
#include "shader_utils.h"
|
#include "shader_utils.h"
|
||||||
|
|
||||||
|
using namespace angle;
|
||||||
|
|
||||||
class MultiWindowSample : public SampleApplication
|
class MultiWindowSample : public SampleApplication
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
|
@ -23,6 +23,8 @@
|
||||||
#define _USE_MATH_DEFINES
|
#define _USE_MATH_DEFINES
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
|
||||||
|
using namespace angle;
|
||||||
|
|
||||||
class ParticleSystemSample : public SampleApplication
|
class ParticleSystemSample : public SampleApplication
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
|
|
||||||
#include "SampleApplication.h"
|
#include "SampleApplication.h"
|
||||||
#include "EGLWindow.h"
|
#include "EGLWindow.h"
|
||||||
|
#include "random_utils.h"
|
||||||
|
|
||||||
SampleApplication::SampleApplication(const std::string &name,
|
SampleApplication::SampleApplication(const std::string &name,
|
||||||
size_t width,
|
size_t width,
|
||||||
|
@ -29,6 +30,8 @@ SampleApplication::SampleApplication(const std::string &name,
|
||||||
|
|
||||||
// Disable vsync
|
// Disable vsync
|
||||||
mEGLWindow->setSwapInterval(0);
|
mEGLWindow->setSwapInterval(0);
|
||||||
|
|
||||||
|
angle::RandomInitFromTime();
|
||||||
}
|
}
|
||||||
|
|
||||||
SampleApplication::~SampleApplication()
|
SampleApplication::~SampleApplication()
|
||||||
|
|
|
@ -21,6 +21,7 @@
|
||||||
'<(angle_path)/src/tests/perf_tests/DrawCallPerf.cpp',
|
'<(angle_path)/src/tests/perf_tests/DrawCallPerf.cpp',
|
||||||
'<(angle_path)/src/tests/perf_tests/EGLInitializePerf.cpp',
|
'<(angle_path)/src/tests/perf_tests/EGLInitializePerf.cpp',
|
||||||
'<(angle_path)/src/tests/perf_tests/IndexConversionPerf.cpp',
|
'<(angle_path)/src/tests/perf_tests/IndexConversionPerf.cpp',
|
||||||
|
'<(angle_path)/src/tests/perf_tests/InstancingPerf.cpp',
|
||||||
'<(angle_path)/src/tests/perf_tests/InterleavedAttributeData.cpp',
|
'<(angle_path)/src/tests/perf_tests/InterleavedAttributeData.cpp',
|
||||||
'<(angle_path)/src/tests/perf_tests/PointSprites.cpp',
|
'<(angle_path)/src/tests/perf_tests/PointSprites.cpp',
|
||||||
'<(angle_path)/src/tests/perf_tests/TexSubImage.cpp',
|
'<(angle_path)/src/tests/perf_tests/TexSubImage.cpp',
|
||||||
|
|
|
@ -0,0 +1,365 @@
|
||||||
|
//
|
||||||
|
// Copyright 2015 The ANGLE Project Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style license that can be
|
||||||
|
// found in the LICENSE file.
|
||||||
|
//
|
||||||
|
// InstancingPerf:
|
||||||
|
// Performance tests for ANGLE instanced draw calls.
|
||||||
|
//
|
||||||
|
|
||||||
|
#include <sstream>
|
||||||
|
|
||||||
|
#include "ANGLEPerfTest.h"
|
||||||
|
#include "Matrix.h"
|
||||||
|
#include "random_utils.h"
|
||||||
|
#include "shader_utils.h"
|
||||||
|
#include "Vector.h"
|
||||||
|
|
||||||
|
using namespace angle;
|
||||||
|
using namespace egl_platform;
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
|
||||||
|
float AnimationSignal(float t)
|
||||||
|
{
|
||||||
|
float l = t / 2.0f;
|
||||||
|
float f = l - floor(l);
|
||||||
|
return (f > 0.5f ? 1.0f - f : f) * 4.0f - 1.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
size_t VectorSizeBytes(const std::vector<T> &vec)
|
||||||
|
{
|
||||||
|
return sizeof(T) * vec.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
struct InstancingPerfParams final : public RenderTestParams
|
||||||
|
{
|
||||||
|
// Common default options
|
||||||
|
InstancingPerfParams()
|
||||||
|
{
|
||||||
|
majorVersion = 2;
|
||||||
|
minorVersion = 0;
|
||||||
|
windowWidth = 256;
|
||||||
|
windowHeight = 256;
|
||||||
|
iterations = 1;
|
||||||
|
runTimeSeconds = 10.0;
|
||||||
|
animationEnabled = false;
|
||||||
|
instancingEnabled = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string suffix() const override
|
||||||
|
{
|
||||||
|
std::stringstream strstr;
|
||||||
|
|
||||||
|
strstr << RenderTestParams::suffix();
|
||||||
|
|
||||||
|
if (!instancingEnabled)
|
||||||
|
{
|
||||||
|
strstr << "_billboards";
|
||||||
|
}
|
||||||
|
|
||||||
|
return strstr.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int iterations;
|
||||||
|
double runTimeSeconds;
|
||||||
|
bool animationEnabled;
|
||||||
|
bool instancingEnabled;
|
||||||
|
};
|
||||||
|
|
||||||
|
std::ostream &operator<<(std::ostream &os, const InstancingPerfParams ¶ms)
|
||||||
|
{
|
||||||
|
os << params.suffix().substr(1);
|
||||||
|
return os;
|
||||||
|
}
|
||||||
|
|
||||||
|
class InstancingPerfBenchmark : public ANGLERenderTest,
|
||||||
|
public ::testing::WithParamInterface<InstancingPerfParams>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
InstancingPerfBenchmark();
|
||||||
|
|
||||||
|
void initializeBenchmark() override;
|
||||||
|
void destroyBenchmark() override;
|
||||||
|
void beginDrawBenchmark() override;
|
||||||
|
void drawBenchmark() override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
GLuint mProgram;
|
||||||
|
std::vector<GLuint> mBuffers;
|
||||||
|
GLuint mNumPoints;
|
||||||
|
std::vector<Vector3> mTranslateData;
|
||||||
|
std::vector<float> mSizeData;
|
||||||
|
std::vector<Vector3> mColorData;
|
||||||
|
};
|
||||||
|
|
||||||
|
InstancingPerfBenchmark::InstancingPerfBenchmark()
|
||||||
|
: ANGLERenderTest("InstancingPerf", GetParam()), mProgram(0), mNumPoints(75000)
|
||||||
|
{
|
||||||
|
mRunTimeSeconds = GetParam().runTimeSeconds;
|
||||||
|
}
|
||||||
|
|
||||||
|
void InstancingPerfBenchmark::initializeBenchmark()
|
||||||
|
{
|
||||||
|
const auto ¶ms = GetParam();
|
||||||
|
|
||||||
|
ASSERT_TRUE(params.iterations > 0);
|
||||||
|
mDrawIterations = params.iterations;
|
||||||
|
|
||||||
|
const std::string vs =
|
||||||
|
"attribute vec2 aPosition;\n"
|
||||||
|
"attribute vec3 aTranslate;\n"
|
||||||
|
"attribute float aScale;\n"
|
||||||
|
"attribute vec3 aColor;\n"
|
||||||
|
"uniform mat4 uWorldMatrix;\n"
|
||||||
|
"uniform mat4 uProjectionMatrix;\n"
|
||||||
|
"varying vec3 vColor;\n"
|
||||||
|
"void main()\n"
|
||||||
|
"{\n"
|
||||||
|
" vec4 position = uWorldMatrix * vec4(aTranslate, 1.0);\n"
|
||||||
|
" position.xy += aPosition * aScale;\n"
|
||||||
|
" gl_Position = uProjectionMatrix * position;\n"
|
||||||
|
" vColor = aColor;\n"
|
||||||
|
"}\n";
|
||||||
|
|
||||||
|
const std::string fs =
|
||||||
|
"precision mediump float;\n"
|
||||||
|
"varying vec3 vColor;\n"
|
||||||
|
"void main()\n"
|
||||||
|
"{\n"
|
||||||
|
" gl_FragColor = vec4(vColor, 1.0);\n"
|
||||||
|
"}\n";
|
||||||
|
|
||||||
|
mProgram = CompileProgram(vs, fs);
|
||||||
|
ASSERT_TRUE(mProgram != 0);
|
||||||
|
|
||||||
|
glUseProgram(mProgram);
|
||||||
|
|
||||||
|
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
|
||||||
|
|
||||||
|
GLuint baseIndexData[6] = {0, 1, 2, 1, 3, 2};
|
||||||
|
Vector2 basePositionData[4] = {Vector2(-1.0f, 1.0f), Vector2(1.0f, 1.0f), Vector2(-1.0f, -1.0f),
|
||||||
|
Vector2(1.0f, -1.0f)};
|
||||||
|
|
||||||
|
std::vector<GLuint> indexData;
|
||||||
|
std::vector<Vector2> positionData;
|
||||||
|
|
||||||
|
if (!params.instancingEnabled)
|
||||||
|
{
|
||||||
|
GLuint pointVertexStride = 4;
|
||||||
|
for (GLuint pointIndex = 0; pointIndex < mNumPoints; ++pointIndex)
|
||||||
|
{
|
||||||
|
for (GLuint indexIndex = 0; indexIndex < 6; ++indexIndex)
|
||||||
|
{
|
||||||
|
indexData.push_back(baseIndexData[indexIndex] + pointIndex * pointVertexStride);
|
||||||
|
}
|
||||||
|
|
||||||
|
Vector3 randVec(RandomNegativeOneToOne(), RandomNegativeOneToOne(),
|
||||||
|
RandomNegativeOneToOne());
|
||||||
|
for (GLuint vertexIndex = 0; vertexIndex < 4; ++vertexIndex)
|
||||||
|
{
|
||||||
|
positionData.push_back(basePositionData[vertexIndex]);
|
||||||
|
mTranslateData.push_back(randVec);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mSizeData.resize(mNumPoints * 4, 0.012f);
|
||||||
|
mColorData.resize(mNumPoints * 4, Vector3(1.0f, 0.0f, 0.0f));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (GLuint index : baseIndexData)
|
||||||
|
{
|
||||||
|
indexData.push_back(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const Vector2 &position : basePositionData)
|
||||||
|
{
|
||||||
|
positionData.push_back(position);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (GLuint pointIndex = 0; pointIndex < mNumPoints; ++pointIndex)
|
||||||
|
{
|
||||||
|
Vector3 randVec(RandomNegativeOneToOne(), RandomNegativeOneToOne(),
|
||||||
|
RandomNegativeOneToOne());
|
||||||
|
mTranslateData.push_back(randVec);
|
||||||
|
}
|
||||||
|
|
||||||
|
mSizeData.resize(mNumPoints, 0.012f);
|
||||||
|
mColorData.resize(mNumPoints, Vector3(1.0f, 0.0f, 0.0f));
|
||||||
|
}
|
||||||
|
|
||||||
|
mBuffers.resize(5, 0);
|
||||||
|
glGenBuffers(static_cast<GLsizei>(mBuffers.size()), &mBuffers[0]);
|
||||||
|
|
||||||
|
// Index Data
|
||||||
|
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mBuffers[0]);
|
||||||
|
glBufferData(GL_ELEMENT_ARRAY_BUFFER, VectorSizeBytes(indexData), &indexData[0],
|
||||||
|
GL_STATIC_DRAW);
|
||||||
|
|
||||||
|
// Position Data
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, mBuffers[1]);
|
||||||
|
glBufferData(GL_ARRAY_BUFFER, VectorSizeBytes(positionData), &positionData[0], GL_STATIC_DRAW);
|
||||||
|
GLint positionLocation = glGetAttribLocation(mProgram, "aPosition");
|
||||||
|
ASSERT_NE(-1, positionLocation);
|
||||||
|
glVertexAttribPointer(positionLocation, 2, GL_FLOAT, GL_FALSE, 8, nullptr);
|
||||||
|
glEnableVertexAttribArray(positionLocation);
|
||||||
|
|
||||||
|
// Translate Data
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, mBuffers[2]);
|
||||||
|
glBufferData(GL_ARRAY_BUFFER, VectorSizeBytes(mTranslateData), &mTranslateData[0],
|
||||||
|
GL_STATIC_DRAW);
|
||||||
|
GLint translateLocation = glGetAttribLocation(mProgram, "aTranslate");
|
||||||
|
ASSERT_NE(-1, translateLocation);
|
||||||
|
glVertexAttribPointer(translateLocation, 3, GL_FLOAT, GL_FALSE, 12, nullptr);
|
||||||
|
glEnableVertexAttribArray(translateLocation);
|
||||||
|
glVertexAttribDivisorANGLE(translateLocation, 1);
|
||||||
|
|
||||||
|
// Scale Data
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, mBuffers[3]);
|
||||||
|
glBufferData(GL_ARRAY_BUFFER, VectorSizeBytes(mSizeData), nullptr, GL_DYNAMIC_DRAW);
|
||||||
|
GLint scaleLocation = glGetAttribLocation(mProgram, "aScale");
|
||||||
|
ASSERT_NE(-1, scaleLocation);
|
||||||
|
glVertexAttribPointer(scaleLocation, 1, GL_FLOAT, GL_FALSE, 4, nullptr);
|
||||||
|
glEnableVertexAttribArray(scaleLocation);
|
||||||
|
glVertexAttribDivisorANGLE(scaleLocation, 1);
|
||||||
|
|
||||||
|
// Color Data
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, mBuffers[4]);
|
||||||
|
glBufferData(GL_ARRAY_BUFFER, VectorSizeBytes(mColorData), nullptr, GL_DYNAMIC_DRAW);
|
||||||
|
GLint colorLocation = glGetAttribLocation(mProgram, "aColor");
|
||||||
|
ASSERT_NE(-1, colorLocation);
|
||||||
|
glVertexAttribPointer(colorLocation, 3, GL_FLOAT, GL_FALSE, 12, nullptr);
|
||||||
|
glEnableVertexAttribArray(colorLocation);
|
||||||
|
glVertexAttribDivisorANGLE(colorLocation, 1);
|
||||||
|
|
||||||
|
// Set the viewport
|
||||||
|
glViewport(0, 0, getWindow()->getWidth(), getWindow()->getHeight());
|
||||||
|
|
||||||
|
// Init matrices
|
||||||
|
GLint worldMatrixLocation = glGetUniformLocation(mProgram, "uWorldMatrix");
|
||||||
|
ASSERT_NE(-1, worldMatrixLocation);
|
||||||
|
Matrix4 worldMatrix = Matrix4::translate(Vector3(0, 0, -3.0f));
|
||||||
|
worldMatrix *= Matrix4::rotate(25.0f, Vector3(0.6f, 1.0f, 0.0f));
|
||||||
|
glUniformMatrix4fv(worldMatrixLocation, 1, GL_FALSE, &worldMatrix.data[0]);
|
||||||
|
|
||||||
|
GLint projectionMatrixLocation = glGetUniformLocation(mProgram, "uProjectionMatrix");
|
||||||
|
ASSERT_NE(-1, projectionMatrixLocation);
|
||||||
|
float fov =
|
||||||
|
static_cast<float>(getWindow()->getWidth()) / static_cast<float>(getWindow()->getHeight());
|
||||||
|
Matrix4 projectionMatrix = Matrix4::perspective(60.0f, fov, 1.0f, 300.0f);
|
||||||
|
glUniformMatrix4fv(projectionMatrixLocation, 1, GL_FALSE, &projectionMatrix.data[0]);
|
||||||
|
|
||||||
|
getWindow()->setVisible(true);
|
||||||
|
|
||||||
|
ASSERT_GL_NO_ERROR();
|
||||||
|
}
|
||||||
|
|
||||||
|
void InstancingPerfBenchmark::destroyBenchmark()
|
||||||
|
{
|
||||||
|
glDeleteProgram(mProgram);
|
||||||
|
|
||||||
|
if (!mBuffers.empty())
|
||||||
|
{
|
||||||
|
glDeleteBuffers(static_cast<GLsizei>(mBuffers.size()), &mBuffers[0]);
|
||||||
|
mBuffers.clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void InstancingPerfBenchmark::beginDrawBenchmark()
|
||||||
|
{
|
||||||
|
glClear(GL_COLOR_BUFFER_BIT);
|
||||||
|
}
|
||||||
|
|
||||||
|
void InstancingPerfBenchmark::drawBenchmark()
|
||||||
|
{
|
||||||
|
const auto ¶ms = GetParam();
|
||||||
|
|
||||||
|
// Animatino makes the test more interesting visually, but also eats up many CPU cycles.
|
||||||
|
if (params.animationEnabled)
|
||||||
|
{
|
||||||
|
// Not implemented for billboards.
|
||||||
|
ASSERT(params.instancingEnabled);
|
||||||
|
|
||||||
|
float time = static_cast<float>(mTimer->getElapsedTime());
|
||||||
|
|
||||||
|
for (size_t pointIndex = 0; pointIndex < mTranslateData.size(); ++pointIndex)
|
||||||
|
{
|
||||||
|
const Vector3 &translate = mTranslateData[pointIndex];
|
||||||
|
|
||||||
|
float tx = translate.x + time;
|
||||||
|
float ty = translate.y + time;
|
||||||
|
float tz = translate.z + time;
|
||||||
|
|
||||||
|
float scale = AnimationSignal(tx) * 0.01f + 0.01f;
|
||||||
|
mSizeData[pointIndex] = scale;
|
||||||
|
|
||||||
|
Vector3 color;
|
||||||
|
color.x = AnimationSignal(tx) * 0.5f + 0.5f;
|
||||||
|
color.y = AnimationSignal(ty) * 0.5f + 0.5f;
|
||||||
|
color.z = AnimationSignal(tz) * 0.5f + 0.5f;
|
||||||
|
|
||||||
|
mColorData[pointIndex] = color;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update scales and colors.
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, mBuffers[3]);
|
||||||
|
glBufferSubData(GL_ARRAY_BUFFER, 0, VectorSizeBytes(mSizeData), &mSizeData[0]);
|
||||||
|
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, mBuffers[4]);
|
||||||
|
glBufferSubData(GL_ARRAY_BUFFER, 0, VectorSizeBytes(mColorData), &mColorData[0]);
|
||||||
|
|
||||||
|
// Render the instances/billboards.
|
||||||
|
if (params.instancingEnabled)
|
||||||
|
{
|
||||||
|
for (unsigned int it = 0; it < params.iterations; it++)
|
||||||
|
{
|
||||||
|
glDrawElementsInstancedANGLE(GL_TRIANGLES, 6, GL_UNSIGNED_INT, nullptr, mNumPoints);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (unsigned int it = 0; it < params.iterations; it++)
|
||||||
|
{
|
||||||
|
glDrawElements(GL_TRIANGLES, 6 * mNumPoints, GL_UNSIGNED_INT, nullptr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ASSERT_GL_NO_ERROR();
|
||||||
|
}
|
||||||
|
|
||||||
|
InstancingPerfParams InstancingPerfD3D11Params()
|
||||||
|
{
|
||||||
|
InstancingPerfParams params;
|
||||||
|
params.eglParameters = D3D11();
|
||||||
|
return params;
|
||||||
|
}
|
||||||
|
|
||||||
|
InstancingPerfParams InstancingPerfD3D9Params()
|
||||||
|
{
|
||||||
|
InstancingPerfParams params;
|
||||||
|
params.eglParameters = D3D9();
|
||||||
|
return params;
|
||||||
|
}
|
||||||
|
|
||||||
|
InstancingPerfParams InstancingPerfOpenGLParams()
|
||||||
|
{
|
||||||
|
InstancingPerfParams params;
|
||||||
|
params.eglParameters = OPENGL();
|
||||||
|
return params;
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_P(InstancingPerfBenchmark, Run)
|
||||||
|
{
|
||||||
|
run();
|
||||||
|
}
|
||||||
|
|
||||||
|
ANGLE_INSTANTIATE_TEST(InstancingPerfBenchmark,
|
||||||
|
InstancingPerfD3D11Params(),
|
||||||
|
InstancingPerfD3D9Params(),
|
||||||
|
InstancingPerfOpenGLParams());
|
||||||
|
|
||||||
|
} // anonymous namespace
|
|
@ -3,20 +3,35 @@
|
||||||
// Use of this source code is governed by a BSD-style license that can be
|
// Use of this source code is governed by a BSD-style license that can be
|
||||||
// found in the LICENSE file.
|
// found in the LICENSE file.
|
||||||
//
|
//
|
||||||
|
// random_utils:
|
||||||
|
// Helper functions for random number generation.
|
||||||
|
//
|
||||||
|
|
||||||
#include "random_utils.h"
|
#include "random_utils.h"
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
|
|
||||||
|
namespace angle
|
||||||
|
{
|
||||||
|
|
||||||
|
void RandomInitFromTime()
|
||||||
|
{
|
||||||
|
srand(static_cast<unsigned int>(time(NULL)));
|
||||||
|
}
|
||||||
|
|
||||||
|
float RandomFloat()
|
||||||
|
{
|
||||||
|
return static_cast<float>(rand()) / static_cast<float>(RAND_MAX);
|
||||||
|
}
|
||||||
|
|
||||||
float RandomBetween(float min, float max)
|
float RandomBetween(float min, float max)
|
||||||
{
|
{
|
||||||
static bool randInitialized = false;
|
return min + RandomFloat() * (max - min);
|
||||||
if (!randInitialized)
|
|
||||||
{
|
|
||||||
srand(static_cast<unsigned int>(time(NULL)));
|
|
||||||
randInitialized = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
const size_t divisor = 10000;
|
|
||||||
return min + ((rand() % divisor) / static_cast<float>(divisor)) * (max - min);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
float RandomNegativeOneToOne()
|
||||||
|
{
|
||||||
|
return RandomBetween(0.0f, 1.0f);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace angle
|
||||||
|
|
|
@ -3,10 +3,22 @@
|
||||||
// Use of this source code is governed by a BSD-style license that can be
|
// Use of this source code is governed by a BSD-style license that can be
|
||||||
// found in the LICENSE file.
|
// found in the LICENSE file.
|
||||||
//
|
//
|
||||||
|
// random_utils:
|
||||||
|
// Helper functions for random number generation.
|
||||||
|
//
|
||||||
|
|
||||||
#ifndef UTIL_RANDOM_UTILS_H
|
#ifndef UTIL_RANDOM_UTILS_H
|
||||||
#define UTIL_RANDOM_UTILS_H
|
#define UTIL_RANDOM_UTILS_H
|
||||||
|
|
||||||
|
namespace angle
|
||||||
|
{
|
||||||
|
|
||||||
|
// TODO(jmadill): Should make this a class
|
||||||
|
void RandomInitFromTime();
|
||||||
|
float RandomFloat();
|
||||||
float RandomBetween(float min, float max);
|
float RandomBetween(float min, float max);
|
||||||
|
float RandomNegativeOneToOne();
|
||||||
|
|
||||||
|
} // namespace angle
|
||||||
|
|
||||||
#endif // UTIL_RANDOM_UTILS_H
|
#endif // UTIL_RANDOM_UTILS_H
|
||||||
|
|
|
@ -46,10 +46,16 @@ GLuint CompileShader(GLenum type, const std::string &source)
|
||||||
GLint infoLogLength;
|
GLint infoLogLength;
|
||||||
glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLogLength);
|
glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLogLength);
|
||||||
|
|
||||||
|
if (infoLogLength > 0)
|
||||||
|
{
|
||||||
std::vector<GLchar> infoLog(infoLogLength);
|
std::vector<GLchar> infoLog(infoLogLength);
|
||||||
glGetShaderInfoLog(shader, static_cast<GLsizei>(infoLog.size()), NULL, &infoLog[0]);
|
glGetShaderInfoLog(shader, static_cast<GLsizei>(infoLog.size()), NULL, &infoLog[0]);
|
||||||
|
|
||||||
std::cerr << "shader compilation failed: " << &infoLog[0];
|
std::cerr << "shader compilation failed: " << &infoLog[0];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
std::cerr << "shader compilation failed. <Empty log message>";
|
||||||
|
}
|
||||||
|
|
||||||
glDeleteShader(shader);
|
glDeleteShader(shader);
|
||||||
shader = 0;
|
shader = 0;
|
||||||
|
|
Загрузка…
Ссылка в новой задаче