mirror of
https://github.com/godotengine/godot-angle-static.git
synced 2026-01-06 02:09:55 +03:00
Vulkan: Fix dirty element array buffer updates.
The issue occurs that binds the same buffer and calls glDrawElements with the same indices. The offset has been reset in the VertexArrayVk::syncState(), but it doesn't check the actual value in the ContextVk::setupIndexedDraw(). Also corrected case where update via BufferSubData wasn't being sent to the HW. Bug: angleproject:3362 Change-Id: I0f7d2fc162bc8f1c36cb09ba689fd27b482b9035 Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/1666345 Commit-Queue: Courtney Goeltzenleuchter <courtneygo@google.com> Reviewed-by: Shahbaz Youssefi <syoussefi@chromium.org>
This commit is contained in:
committed by
Commit Bot
parent
661ed41972
commit
b867bc6f10
@@ -25,6 +25,7 @@ Google Inc.
|
||||
Eric Boren
|
||||
Henry Bridge
|
||||
Nat Duca
|
||||
Courtney Goeltzenleuchter
|
||||
Peter Kasting
|
||||
Vangelis Kokkevis
|
||||
Zhenyao Mo
|
||||
|
||||
@@ -481,10 +481,12 @@ angle::Result ContextVk::setupIndexedDraw(const gl::Context *context,
|
||||
const void *indices,
|
||||
vk::CommandBuffer **commandBufferOut)
|
||||
{
|
||||
ASSERT(mode != gl::PrimitiveMode::LineLoop);
|
||||
|
||||
if (indexType != mCurrentDrawElementsType)
|
||||
{
|
||||
mDirtyBits.set(DIRTY_BIT_INDEX_BUFFER);
|
||||
mCurrentDrawElementsType = indexType;
|
||||
setIndexBufferDirty();
|
||||
}
|
||||
|
||||
const gl::Buffer *elementArrayBuffer = mVertexArray->getState().getElementArrayBuffer();
|
||||
@@ -524,7 +526,7 @@ angle::Result ContextVk::setupLineLoopDraw(const gl::Context *context,
|
||||
{
|
||||
ANGLE_TRY(mVertexArray->handleLineLoop(this, firstVertex, vertexOrIndexCount,
|
||||
indexTypeOrInvalid, indices, numIndicesOut));
|
||||
mDirtyBits.set(DIRTY_BIT_INDEX_BUFFER);
|
||||
setIndexBufferDirty();
|
||||
mCurrentDrawElementsType = indexTypeOrInvalid != gl::DrawElementsType::InvalidEnum
|
||||
? indexTypeOrInvalid
|
||||
: gl::DrawElementsType::UnsignedInt;
|
||||
|
||||
@@ -232,7 +232,11 @@ class ContextVk : public ContextImpl, public vk::Context, public vk::CommandBuff
|
||||
unsigned int line) override;
|
||||
const gl::ActiveTextureArray<TextureVk *> &getActiveTextures() const;
|
||||
|
||||
void setIndexBufferDirty() { mDirtyBits.set(DIRTY_BIT_INDEX_BUFFER); }
|
||||
void setIndexBufferDirty()
|
||||
{
|
||||
mDirtyBits.set(DIRTY_BIT_INDEX_BUFFER);
|
||||
mLastIndexBufferOffset = reinterpret_cast<const void *>(angle::DirtyPointer);
|
||||
}
|
||||
|
||||
angle::Result flushImpl(const gl::Semaphore *semaphore);
|
||||
angle::Result finishImpl();
|
||||
|
||||
@@ -345,7 +345,6 @@ angle::Result VertexArrayVk::syncState(const gl::Context *context,
|
||||
mCurrentElementArrayBuffer = nullptr;
|
||||
}
|
||||
|
||||
mCurrentElementArrayBufferOffset = 0;
|
||||
mLineLoopBufferFirstIndex.reset();
|
||||
mLineLoopBufferLastIndex.reset();
|
||||
contextVk->setIndexBufferDirty();
|
||||
@@ -356,6 +355,7 @@ angle::Result VertexArrayVk::syncState(const gl::Context *context,
|
||||
case gl::VertexArray::DIRTY_BIT_ELEMENT_ARRAY_BUFFER_DATA:
|
||||
mLineLoopBufferFirstIndex.reset();
|
||||
mLineLoopBufferLastIndex.reset();
|
||||
contextVk->setIndexBufferDirty();
|
||||
mDirtyLineLoopTranslation = true;
|
||||
break;
|
||||
|
||||
|
||||
@@ -1248,6 +1248,68 @@ TEST_P(LineLoopStateChangeTest, DrawArraysThenDrawElements)
|
||||
validateSquareAndHourglass();
|
||||
}
|
||||
|
||||
// Draw a triangle with a drawElements call and a non-zero offset and draw the same
|
||||
// triangle with the same offset again followed by a line loop with drawElements.
|
||||
TEST_P(LineLoopStateChangeTest, DrawElementsThenDrawElements)
|
||||
{
|
||||
ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Simple(), essl1_shaders::fs::Blue());
|
||||
|
||||
glUseProgram(program);
|
||||
|
||||
// Background Red color
|
||||
glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
|
||||
// We expect to draw a triangle with the last three points on the bottom right,
|
||||
// draw with LineLoop, and then draw a triangle with the same non-zero offset.
|
||||
auto vertices = std::vector<Vector3>{
|
||||
{-1.0f, 1.0f, 0.0f}, {1.0f, 1.0f, 0.0f}, {1.0f, -1.0f, 0.0f}, {-1.0f, -1.0f, 0.0f}};
|
||||
|
||||
auto indices = std::vector<GLushort>{0, 1, 2, 1, 2, 3};
|
||||
|
||||
GLint positionLocation = glGetAttribLocation(program, essl1_shaders::PositionAttrib());
|
||||
ASSERT_NE(-1, positionLocation);
|
||||
|
||||
GLBuffer indexBuffer;
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBuffer);
|
||||
glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.size() * sizeof(GLushort), &indices[0],
|
||||
GL_STATIC_DRAW);
|
||||
|
||||
GLBuffer vertexBuffer;
|
||||
glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
|
||||
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices[0]) * vertices.size(), vertices.data(),
|
||||
GL_STATIC_DRAW);
|
||||
|
||||
glVertexAttribPointer(positionLocation, 3, GL_FLOAT, GL_FALSE, 0, nullptr);
|
||||
glEnableVertexAttribArray(positionLocation);
|
||||
|
||||
// Draw a triangle with a non-zero offset on the bottom right.
|
||||
glDrawElements(GL_TRIANGLES, 3, GL_UNSIGNED_SHORT, (void *)(3 * sizeof(GLushort)));
|
||||
|
||||
// Draw with LineLoop.
|
||||
glDrawElements(GL_LINE_LOOP, 3, GL_UNSIGNED_SHORT, nullptr);
|
||||
|
||||
// Draw the triangle again with the same offset.
|
||||
glDrawElements(GL_TRIANGLES, 3, GL_UNSIGNED_SHORT, (void *)(3 * sizeof(GLushort)));
|
||||
|
||||
glDisableVertexAttribArray(positionLocation);
|
||||
|
||||
ASSERT_GL_NO_ERROR();
|
||||
|
||||
int quarterWidth = getWindowWidth() / 4;
|
||||
int quarterHeight = getWindowHeight() / 4;
|
||||
|
||||
// Validate the top left point's color.
|
||||
EXPECT_PIXEL_COLOR_EQ(0, getWindowHeight() - 1, GLColor::blue);
|
||||
|
||||
// Validate the triangle is drawn on the bottom right.
|
||||
EXPECT_PIXEL_COLOR_EQ(quarterWidth * 2, quarterHeight, GLColor::blue);
|
||||
|
||||
// Validate the triangle is NOT on the top left part.
|
||||
EXPECT_PIXEL_COLOR_EQ(quarterWidth * 2, quarterHeight * 3, GLColor::red);
|
||||
EXPECT_PIXEL_COLOR_EQ(quarterWidth, quarterHeight * 2, GLColor::red);
|
||||
}
|
||||
|
||||
// Simple state change tests, primarily focused on basic object lifetime and dependency management
|
||||
// with back-ends that don't support that automatically (i.e. Vulkan).
|
||||
class SimpleStateChangeTest : public ANGLETest
|
||||
@@ -1430,6 +1492,282 @@ TEST_P(SimpleStateChangeTest, DrawArraysThenDrawElements)
|
||||
EXPECT_PIXEL_COLOR_EQ((quarterWidth * 3), halfHeight, GLColor::blue);
|
||||
}
|
||||
|
||||
// Draw a triangle with drawElements and a non-zero offset and draw the same
|
||||
// triangle with the same offset followed by binding the same element buffer.
|
||||
TEST_P(SimpleStateChangeTest, DrawElementsThenDrawElements)
|
||||
{
|
||||
ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Simple(), essl1_shaders::fs::Blue());
|
||||
|
||||
glUseProgram(program);
|
||||
|
||||
// Background Red color
|
||||
glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
|
||||
// We expect to draw the triangle with the last three points on the bottom right, and
|
||||
// rebind the same element buffer and draw with the same indices.
|
||||
auto vertices = std::vector<Vector3>{
|
||||
{-1.0f, 1.0f, 0.0f}, {1.0f, 1.0f, 0.0f}, {1.0f, -1.0f, 0.0f}, {-1.0f, -1.0f, 0.0f}};
|
||||
|
||||
auto indices = std::vector<GLushort>{0, 1, 2, 1, 2, 3};
|
||||
|
||||
GLint positionLocation = glGetAttribLocation(program, essl1_shaders::PositionAttrib());
|
||||
ASSERT_NE(-1, positionLocation);
|
||||
|
||||
GLBuffer indexBuffer;
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBuffer);
|
||||
glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.size() * sizeof(GLushort), &indices[0],
|
||||
GL_STATIC_DRAW);
|
||||
|
||||
GLBuffer vertexBuffer;
|
||||
glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
|
||||
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices[0]) * vertices.size(), vertices.data(),
|
||||
GL_STATIC_DRAW);
|
||||
|
||||
glVertexAttribPointer(positionLocation, 3, GL_FLOAT, GL_FALSE, 0, nullptr);
|
||||
glEnableVertexAttribArray(positionLocation);
|
||||
|
||||
glDrawElements(GL_TRIANGLES, 3, GL_UNSIGNED_SHORT, (void *)(3 * sizeof(GLushort)));
|
||||
|
||||
// Rebind the same element buffer.
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBuffer);
|
||||
|
||||
// Draw the triangle again with the same offset.
|
||||
glDrawElements(GL_TRIANGLES, 3, GL_UNSIGNED_SHORT, (void *)(3 * sizeof(GLushort)));
|
||||
|
||||
glDisableVertexAttribArray(positionLocation);
|
||||
|
||||
ASSERT_GL_NO_ERROR();
|
||||
|
||||
int quarterWidth = getWindowWidth() / 4;
|
||||
int quarterHeight = getWindowHeight() / 4;
|
||||
|
||||
// Validate the triangle is drawn on the bottom right.
|
||||
EXPECT_PIXEL_COLOR_EQ(quarterWidth * 2, quarterHeight, GLColor::blue);
|
||||
|
||||
// Validate the triangle is NOT on the top left part.
|
||||
EXPECT_PIXEL_COLOR_EQ(quarterWidth * 2, quarterHeight * 3, GLColor::red);
|
||||
EXPECT_PIXEL_COLOR_EQ(quarterWidth, quarterHeight * 2, GLColor::red);
|
||||
}
|
||||
|
||||
// Draw a triangle with drawElements then change the index buffer and draw again.
|
||||
TEST_P(SimpleStateChangeTest, DrawElementsThenDrawElementsNewIndexBuffer)
|
||||
{
|
||||
ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Simple(), essl1_shaders::fs::UniformColor());
|
||||
|
||||
glUseProgram(program);
|
||||
|
||||
// Background Red color
|
||||
glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
|
||||
// We expect to draw the triangle with the last three points on the bottom right, and
|
||||
// rebind the same element buffer and draw with the same indices.
|
||||
auto vertices = std::vector<Vector3>{
|
||||
{-1.0f, 1.0f, 0.0f}, {1.0f, 1.0f, 0.0f}, {1.0f, -1.0f, 0.0f}, {-1.0f, -1.0f, 0.0f}};
|
||||
|
||||
auto indices8 = std::vector<GLubyte>{0, 1, 2, 1, 2, 3};
|
||||
|
||||
GLint positionLocation = glGetAttribLocation(program, essl1_shaders::PositionAttrib());
|
||||
ASSERT_NE(-1, positionLocation);
|
||||
|
||||
GLint colorUniformLocation =
|
||||
glGetUniformLocation(program, angle::essl1_shaders::ColorUniform());
|
||||
ASSERT_NE(colorUniformLocation, -1);
|
||||
|
||||
glUniform4f(colorUniformLocation, 1.0f, 1.0f, 1.0f, 1.0f);
|
||||
|
||||
GLBuffer indexBuffer8;
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBuffer8);
|
||||
glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices8.size() * sizeof(GLubyte), &indices8[0],
|
||||
GL_STATIC_DRAW);
|
||||
|
||||
GLBuffer vertexBuffer;
|
||||
glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
|
||||
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices[0]) * vertices.size(), vertices.data(),
|
||||
GL_STATIC_DRAW);
|
||||
|
||||
glVertexAttribPointer(positionLocation, 3, GL_FLOAT, GL_FALSE, 0, nullptr);
|
||||
glEnableVertexAttribArray(positionLocation);
|
||||
|
||||
glDrawElements(GL_TRIANGLES, 3, GL_UNSIGNED_BYTE, (void *)(0 * sizeof(GLubyte)));
|
||||
|
||||
auto indices2nd8 = std::vector<GLubyte>{2, 3, 0, 0, 1, 2};
|
||||
|
||||
glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices2nd8.size() * sizeof(GLubyte), &indices2nd8[0],
|
||||
GL_STATIC_DRAW);
|
||||
|
||||
glUniform4f(colorUniformLocation, 0.0f, 0.0f, 1.0f, 1.0f);
|
||||
|
||||
// Draw the triangle again with the same offset.
|
||||
glDrawElements(GL_TRIANGLES, 3, GL_UNSIGNED_BYTE, (void *)(0 * sizeof(GLubyte)));
|
||||
|
||||
glDisableVertexAttribArray(positionLocation);
|
||||
|
||||
ASSERT_GL_NO_ERROR();
|
||||
|
||||
int quarterWidth = getWindowWidth() / 4;
|
||||
int quarterHeight = getWindowHeight() / 4;
|
||||
|
||||
// Validate the triangle is drawn on the bottom left.
|
||||
EXPECT_PIXEL_COLOR_EQ(quarterWidth * 2, quarterHeight, GLColor::blue);
|
||||
EXPECT_PIXEL_COLOR_EQ(quarterWidth, quarterHeight * 2, GLColor::blue);
|
||||
|
||||
// Validate the triangle is NOT on the top right part.
|
||||
EXPECT_PIXEL_COLOR_EQ(quarterWidth * 2, quarterHeight * 3, GLColor::white);
|
||||
}
|
||||
|
||||
// Draw a triangle with drawElements then change the indices and draw again.
|
||||
TEST_P(SimpleStateChangeTest, DrawElementsThenDrawElementsNewIndices)
|
||||
{
|
||||
ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Simple(), essl1_shaders::fs::UniformColor());
|
||||
|
||||
glUseProgram(program);
|
||||
|
||||
// Background Red color
|
||||
glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
|
||||
// We expect to draw the triangle with the last three points on the bottom right, and
|
||||
// rebind the same element buffer and draw with the same indices.
|
||||
auto vertices = std::vector<Vector3>{
|
||||
{-1.0f, 1.0f, 0.0f}, {1.0f, 1.0f, 0.0f}, {1.0f, -1.0f, 0.0f}, {-1.0f, -1.0f, 0.0f}};
|
||||
|
||||
auto indices8 = std::vector<GLubyte>{0, 1, 2, 2, 3, 0};
|
||||
|
||||
GLint positionLocation = glGetAttribLocation(program, essl1_shaders::PositionAttrib());
|
||||
ASSERT_NE(-1, positionLocation);
|
||||
|
||||
GLint colorUniformLocation =
|
||||
glGetUniformLocation(program, angle::essl1_shaders::ColorUniform());
|
||||
ASSERT_NE(colorUniformLocation, -1);
|
||||
|
||||
glUniform4f(colorUniformLocation, 1.0f, 1.0f, 1.0f, 1.0f);
|
||||
|
||||
GLBuffer indexBuffer8;
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBuffer8);
|
||||
glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices8.size() * sizeof(GLubyte), &indices8[0],
|
||||
GL_DYNAMIC_DRAW);
|
||||
|
||||
GLBuffer vertexBuffer;
|
||||
glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
|
||||
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices[0]) * vertices.size(), vertices.data(),
|
||||
GL_STATIC_DRAW);
|
||||
|
||||
glVertexAttribPointer(positionLocation, 3, GL_FLOAT, GL_FALSE, 0, nullptr);
|
||||
glEnableVertexAttribArray(positionLocation);
|
||||
|
||||
glDrawElements(GL_TRIANGLES, 3, GL_UNSIGNED_BYTE, (void *)(0 * sizeof(GLubyte)));
|
||||
|
||||
auto newIndices8 = std::vector<GLubyte>{2, 3, 0};
|
||||
|
||||
glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, 0, newIndices8.size() * sizeof(GLubyte),
|
||||
&newIndices8[0]);
|
||||
|
||||
glUniform4f(colorUniformLocation, 0.0f, 0.0f, 1.0f, 1.0f);
|
||||
|
||||
// Draw the triangle again with the same offset.
|
||||
glDrawElements(GL_TRIANGLES, 3, GL_UNSIGNED_BYTE, (void *)(0 * sizeof(GLubyte)));
|
||||
|
||||
glDisableVertexAttribArray(positionLocation);
|
||||
|
||||
ASSERT_GL_NO_ERROR();
|
||||
|
||||
int quarterWidth = getWindowWidth() / 4;
|
||||
int quarterHeight = getWindowHeight() / 4;
|
||||
|
||||
// Validate the triangle is drawn on the bottom left.
|
||||
EXPECT_PIXEL_COLOR_EQ(quarterWidth * 2, quarterHeight, GLColor::blue);
|
||||
EXPECT_PIXEL_COLOR_EQ(quarterWidth, quarterHeight * 2, GLColor::blue);
|
||||
|
||||
// Validate the triangle is NOT on the top right part.
|
||||
EXPECT_PIXEL_COLOR_EQ(quarterWidth * 2, quarterHeight * 3, GLColor::white);
|
||||
}
|
||||
|
||||
// Draw a triangle with drawElements and a non-zero offset and draw the same
|
||||
// triangle with the same offset followed by binding a USHORT element buffer.
|
||||
TEST_P(SimpleStateChangeTest, DrawElementsUBYTEX2ThenDrawElementsUSHORT)
|
||||
{
|
||||
ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Simple(), essl1_shaders::fs::UniformColor());
|
||||
|
||||
glUseProgram(program);
|
||||
|
||||
// Background Red color
|
||||
glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
|
||||
// We expect to draw the triangle with the last three points on the bottom right, and
|
||||
// rebind the same element buffer and draw with the same indices.
|
||||
auto vertices = std::vector<Vector3>{
|
||||
{-1.0f, 1.0f, 0.0f}, {1.0f, 1.0f, 0.0f}, {1.0f, -1.0f, 0.0f}, {-1.0f, -1.0f, 0.0f}};
|
||||
|
||||
auto indices8 = std::vector<GLubyte>{0, 1, 2, 1, 2, 3};
|
||||
|
||||
GLint positionLocation = glGetAttribLocation(program, essl1_shaders::PositionAttrib());
|
||||
ASSERT_NE(-1, positionLocation);
|
||||
|
||||
GLint colorUniformLocation =
|
||||
glGetUniformLocation(program, angle::essl1_shaders::ColorUniform());
|
||||
ASSERT_NE(colorUniformLocation, -1);
|
||||
|
||||
glUniform4f(colorUniformLocation, 1.0f, 1.0f, 1.0f, 1.0f);
|
||||
|
||||
GLBuffer indexBuffer8;
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBuffer8);
|
||||
glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices8.size() * sizeof(GLubyte), &indices8[0],
|
||||
GL_STATIC_DRAW);
|
||||
|
||||
GLBuffer vertexBuffer;
|
||||
glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
|
||||
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices[0]) * vertices.size(), vertices.data(),
|
||||
GL_STATIC_DRAW);
|
||||
|
||||
glVertexAttribPointer(positionLocation, 3, GL_FLOAT, GL_FALSE, 0, nullptr);
|
||||
glEnableVertexAttribArray(positionLocation);
|
||||
|
||||
glDrawElements(GL_TRIANGLES, 3, GL_UNSIGNED_BYTE, (void *)(0 * sizeof(GLubyte)));
|
||||
|
||||
auto indices2nd8 = std::vector<GLubyte>{2, 3, 0, 0, 1, 2};
|
||||
GLBuffer indexBuffer2nd8;
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBuffer2nd8);
|
||||
glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices2nd8.size() * sizeof(GLubyte), &indices2nd8[0],
|
||||
GL_STATIC_DRAW);
|
||||
glUniform4f(colorUniformLocation, 0.0f, 1.0f, 0.0f, 1.0f);
|
||||
|
||||
glDrawElements(GL_TRIANGLES, 3, GL_UNSIGNED_BYTE, (void *)(0 * sizeof(GLubyte)));
|
||||
|
||||
// Bind the 16bit element buffer.
|
||||
auto indices16 = std::vector<GLushort>{0, 1, 3, 1, 2, 3};
|
||||
GLBuffer indexBuffer16;
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBuffer16);
|
||||
glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices16.size() * sizeof(GLushort), &indices16[0],
|
||||
GL_STATIC_DRAW);
|
||||
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBuffer16);
|
||||
|
||||
glUniform4f(colorUniformLocation, 0.0f, 0.0f, 1.0f, 1.0f);
|
||||
|
||||
// Draw the triangle again with the same offset.
|
||||
glDrawElements(GL_TRIANGLES, 3, GL_UNSIGNED_SHORT, (void *)(0 * sizeof(GLushort)));
|
||||
|
||||
glDisableVertexAttribArray(positionLocation);
|
||||
|
||||
ASSERT_GL_NO_ERROR();
|
||||
|
||||
int quarterWidth = getWindowWidth() / 4;
|
||||
int quarterHeight = getWindowHeight() / 4;
|
||||
|
||||
// Validate green triangle is drawn on the bottom.
|
||||
EXPECT_PIXEL_COLOR_EQ(quarterWidth * 2, quarterHeight, GLColor::green);
|
||||
|
||||
// Validate white triangle is drawn on the right.
|
||||
EXPECT_PIXEL_COLOR_EQ(quarterWidth * 3, quarterHeight * 2, GLColor::white);
|
||||
|
||||
// Validate blue triangle is on the top left part.
|
||||
EXPECT_PIXEL_COLOR_EQ(quarterWidth * 2, quarterHeight * 3, GLColor::blue);
|
||||
EXPECT_PIXEL_COLOR_EQ(quarterWidth, quarterHeight * 2, GLColor::blue);
|
||||
}
|
||||
|
||||
// Handles deleting a Buffer when it's being used.
|
||||
TEST_P(SimpleStateChangeTest, DeleteBufferInUse)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user