You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
243 lines
7.5 KiB
243 lines
7.5 KiB
4 months ago
|
//
|
||
|
// Copyright 2014 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.
|
||
|
//
|
||
|
|
||
|
// Based on Hello_Triangle.c from
|
||
|
// Book: OpenGL(R) ES 2.0 Programming Guide
|
||
|
// Authors: Aaftab Munshi, Dan Ginsburg, Dave Shreiner
|
||
|
// ISBN-10: 0321502795
|
||
|
// ISBN-13: 9780321502797
|
||
|
// Publisher: Addison-Wesley Professional
|
||
|
// URLs: http://safari.informit.com/9780321563835
|
||
|
// http://www.opengles-book.com
|
||
|
|
||
|
#include "SampleApplication.h"
|
||
|
|
||
|
#include "util/shader_utils.h"
|
||
|
|
||
|
#include <cstring>
|
||
|
#include <iostream>
|
||
|
|
||
|
// This small sample compares the per-frame render time for a series of
|
||
|
// squares drawn with TRIANGLE_FANS versus squares drawn with TRIANGLES.
|
||
|
// To exacerbate differences between the two, we use a large collection
|
||
|
// of short buffers with pre-translated vertex data.
|
||
|
|
||
|
class TriangleFanBenchSample : public SampleApplication
|
||
|
{
|
||
|
public:
|
||
|
TriangleFanBenchSample(int argc, char **argv)
|
||
|
: SampleApplication("Microbench", argc, argv, 2, 0, 1280, 1280), mFrameCount(0)
|
||
|
{}
|
||
|
|
||
|
void createVertexBuffers()
|
||
|
{
|
||
|
const unsigned int slices = 8;
|
||
|
const unsigned int numFanVertices = slices + 2;
|
||
|
const unsigned int fanFloats = numFanVertices * 3;
|
||
|
|
||
|
mNumFanVerts = numFanVertices;
|
||
|
|
||
|
const GLfloat halfDim = 0.0625;
|
||
|
GLfloat fanVertices[] = {
|
||
|
0.0f, 0.0f, 0.0f, // center
|
||
|
-halfDim, -halfDim, 0.0f, // LL
|
||
|
-halfDim, 0.0f, 0.0f, // CL
|
||
|
-halfDim, halfDim, 0.0f, // UL
|
||
|
0.0f, halfDim, 0.0f, // UC
|
||
|
halfDim, halfDim, 0.0f, // UR
|
||
|
halfDim, 0.0f, 0.0f, // CR
|
||
|
halfDim, -halfDim, 0.0f, // LR
|
||
|
0.0f, -halfDim, 0.0f, // LC
|
||
|
-halfDim, -halfDim, 0.0f // LL (closes the fan)
|
||
|
};
|
||
|
|
||
|
const GLfloat xMin = -1.0f; // We leave viewport/worldview untransformed in this sample
|
||
|
const GLfloat xMax = 1.0f;
|
||
|
const GLfloat yMin = -1.0f;
|
||
|
// const GLfloat yMax = 1.0f;
|
||
|
|
||
|
glGenBuffers(mNumSquares, mFanBufId);
|
||
|
|
||
|
GLfloat xOffset = xMin;
|
||
|
GLfloat yOffset = yMin;
|
||
|
for (unsigned int i = 0; i < mNumSquares; ++i)
|
||
|
{
|
||
|
GLfloat tempVerts[fanFloats] = {0};
|
||
|
for (unsigned int j = 0; j < numFanVertices; ++j)
|
||
|
{
|
||
|
tempVerts[j * 3] = fanVertices[j * 3] + xOffset;
|
||
|
tempVerts[j * 3 + 1] = fanVertices[j * 3 + 1] + yOffset;
|
||
|
tempVerts[j * 3 + 2] = 0.0f;
|
||
|
}
|
||
|
|
||
|
glBindBuffer(GL_ARRAY_BUFFER, mFanBufId[i]);
|
||
|
glBufferData(GL_ARRAY_BUFFER, fanFloats * sizeof(GLfloat), tempVerts, GL_STATIC_DRAW);
|
||
|
|
||
|
xOffset += 2 * halfDim;
|
||
|
if (xOffset > xMax)
|
||
|
{
|
||
|
xOffset = xMin;
|
||
|
yOffset += 2 * halfDim;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
const unsigned int numTriVertices = slices * 3;
|
||
|
const unsigned int triFloats = numTriVertices * 3;
|
||
|
GLfloat triVertices[triFloats];
|
||
|
GLfloat *triPointer = triVertices;
|
||
|
|
||
|
mNumTriVerts = numTriVertices;
|
||
|
|
||
|
for (unsigned int i = 0; i < slices; ++i)
|
||
|
{
|
||
|
memcpy(triPointer, fanVertices,
|
||
|
3 * sizeof(GLfloat)); // copy center point as first vertex for this slice
|
||
|
triPointer += 3;
|
||
|
for (unsigned int j = 1; j < 3; ++j)
|
||
|
{
|
||
|
GLfloat *vertex =
|
||
|
&(fanVertices[(i + j) * 3]); // copy two outer vertices for this point
|
||
|
memcpy(triPointer, vertex, 3 * sizeof(GLfloat));
|
||
|
triPointer += 3;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// GLfloat triVertices2[triFloats];
|
||
|
glGenBuffers(mNumSquares, mTriBufId);
|
||
|
xOffset = xMin;
|
||
|
yOffset = yMin;
|
||
|
|
||
|
for (unsigned int i = 0; i < mNumSquares; ++i)
|
||
|
{
|
||
|
triPointer = triVertices;
|
||
|
GLfloat tempVerts[triFloats];
|
||
|
for (unsigned int j = 0; j < numTriVertices; ++j)
|
||
|
{
|
||
|
tempVerts[j * 3] = triPointer[0] + xOffset;
|
||
|
tempVerts[j * 3 + 1] = triPointer[1] + yOffset;
|
||
|
tempVerts[j * 3 + 2] = 0.0f;
|
||
|
triPointer += 3;
|
||
|
}
|
||
|
|
||
|
glBindBuffer(GL_ARRAY_BUFFER, mTriBufId[i]);
|
||
|
glBufferData(GL_ARRAY_BUFFER, triFloats * sizeof(GLfloat), tempVerts, GL_STATIC_DRAW);
|
||
|
xOffset += 2 * halfDim;
|
||
|
if (xOffset > xMax)
|
||
|
{
|
||
|
yOffset += 2 * halfDim;
|
||
|
xOffset = xMin;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
bool initialize() override
|
||
|
{
|
||
|
constexpr char kVS[] = R"(attribute vec4 vPosition;
|
||
|
void main()
|
||
|
{
|
||
|
gl_Position = vPosition;
|
||
|
})";
|
||
|
|
||
|
constexpr char kFS[] = R"(precision mediump float;
|
||
|
void main()
|
||
|
{
|
||
|
gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
|
||
|
})";
|
||
|
|
||
|
mProgram = CompileProgram(kVS, kFS);
|
||
|
if (!mProgram)
|
||
|
{
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
|
||
|
|
||
|
createVertexBuffers();
|
||
|
|
||
|
mFanTotalTime = 0;
|
||
|
mTriTotalTime = 0;
|
||
|
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
void destroy() override
|
||
|
{
|
||
|
std::cout << "Total draw time using TRIANGLE_FAN: " << mFanTotalTime << "ms ("
|
||
|
<< (float)mFanTotalTime / (float)mFrameCount << " average per frame)"
|
||
|
<< std::endl;
|
||
|
std::cout << "Total draw time using TRIANGLES: " << mTriTotalTime << "ms ("
|
||
|
<< (float)mTriTotalTime / (float)mFrameCount << " average per frame)"
|
||
|
<< std::endl;
|
||
|
glDeleteProgram(mProgram);
|
||
|
}
|
||
|
|
||
|
void draw() override
|
||
|
{
|
||
|
// Set the viewport
|
||
|
glViewport(0, 0, getWindow()->getWidth(), getWindow()->getHeight());
|
||
|
|
||
|
// Clear the color buffer
|
||
|
glClear(GL_COLOR_BUFFER_BIT);
|
||
|
|
||
|
// Use the program object
|
||
|
glUseProgram(mProgram);
|
||
|
|
||
|
// Bind the vertex data
|
||
|
glEnableVertexAttribArray(0);
|
||
|
|
||
|
// Draw using triangle fans, stored in VBO
|
||
|
mFanTimer.start();
|
||
|
for (unsigned i = 0; i < mNumSquares; ++i)
|
||
|
{
|
||
|
glBindBuffer(GL_ARRAY_BUFFER, mFanBufId[i]);
|
||
|
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, nullptr);
|
||
|
glDrawArrays(GL_TRIANGLE_FAN, 0, mNumFanVerts);
|
||
|
}
|
||
|
mFanTimer.stop();
|
||
|
|
||
|
mFanTotalTime += static_cast<unsigned int>(
|
||
|
mFanTimer.getElapsedTime() * 1000); // convert from usec to msec when accumulating
|
||
|
|
||
|
// Clear to eliminate driver-side gains from occlusion
|
||
|
glClear(GL_COLOR_BUFFER_BIT);
|
||
|
|
||
|
// Draw using triangles, stored in VBO
|
||
|
mTriTimer.start();
|
||
|
for (unsigned i = 1; i < mNumSquares; ++i)
|
||
|
{
|
||
|
glBindBuffer(GL_ARRAY_BUFFER, mTriBufId[i]);
|
||
|
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, nullptr);
|
||
|
glDrawArrays(GL_TRIANGLES, 0, mNumTriVerts);
|
||
|
}
|
||
|
mTriTimer.stop();
|
||
|
|
||
|
mTriTotalTime += static_cast<unsigned int>(
|
||
|
mTriTimer.getElapsedTime() * 1000); // convert from usec to msec when accumulating
|
||
|
|
||
|
mFrameCount++;
|
||
|
}
|
||
|
|
||
|
private:
|
||
|
static const unsigned int mNumSquares = 289;
|
||
|
unsigned int mNumFanVerts;
|
||
|
unsigned int mNumTriVerts;
|
||
|
GLuint mProgram;
|
||
|
GLuint mFanBufId[mNumSquares];
|
||
|
GLuint mTriBufId[mNumSquares];
|
||
|
|
||
|
Timer mFanTimer;
|
||
|
Timer mTriTimer;
|
||
|
unsigned int mFrameCount;
|
||
|
unsigned int mTriTotalTime;
|
||
|
unsigned int mFanTotalTime;
|
||
|
};
|
||
|
|
||
|
int main(int argc, char **argv)
|
||
|
{
|
||
|
TriangleFanBenchSample app(argc, argv);
|
||
|
return app.run();
|
||
|
}
|