blob: 31c264e3dcafb7d2446dd9bec3e0908f95764e73 [file] [log] [blame]
Geoff Langf9a6f082015-01-22 13:32:49 -05001//
2// Copyright 2015 The ANGLE Project Authors. All rights reserved.
3// Use of this source code is governed by a BSD-style license that can be
4// found in the LICENSE file.
5//
6
7// VertexArrayGL.cpp: Implements the class methods for VertexArrayGL.
8
9#include "libANGLE/renderer/gl/VertexArrayGL.h"
10
11#include "common/debug.h"
Geoff Lang6ae6efc2015-03-09 14:42:35 -040012#include "libANGLE/Buffer.h"
Geoff Langba4c4a82015-02-24 12:38:46 -050013#include "libANGLE/angletypes.h"
14#include "libANGLE/renderer/gl/BufferGL.h"
15#include "libANGLE/renderer/gl/FunctionsGL.h"
16#include "libANGLE/renderer/gl/StateManagerGL.h"
Geoff Langf9a6f082015-01-22 13:32:49 -050017
18namespace rx
19{
20
Geoff Langba4c4a82015-02-24 12:38:46 -050021VertexArrayGL::VertexArrayGL(const FunctionsGL *functions, StateManagerGL *stateManager)
22 : VertexArrayImpl(),
23 mFunctions(functions),
24 mStateManager(stateManager),
25 mVertexArrayID(0),
Geoff Lang6ae6efc2015-03-09 14:42:35 -040026 mElementArrayBuffer(),
27 mAttributes(),
Geoff Langba4c4a82015-02-24 12:38:46 -050028 mAppliedElementArrayBuffer(0),
29 mAppliedAttributes()
30{
31 ASSERT(mFunctions);
32 ASSERT(mStateManager);
33 mFunctions->genVertexArrays(1, &mVertexArrayID);
34
35 // Set the cached vertex attribute array size
36 GLint maxVertexAttribs;
37 mFunctions->getIntegerv(GL_MAX_VERTEX_ATTRIBS, &maxVertexAttribs);
Geoff Lang6ae6efc2015-03-09 14:42:35 -040038 mAttributes.resize(maxVertexAttribs);
Geoff Langba4c4a82015-02-24 12:38:46 -050039 mAppliedAttributes.resize(maxVertexAttribs);
40}
Geoff Langf9a6f082015-01-22 13:32:49 -050041
42VertexArrayGL::~VertexArrayGL()
Geoff Langba4c4a82015-02-24 12:38:46 -050043{
44 if (mVertexArrayID != 0)
45 {
46 mFunctions->deleteVertexArrays(1, &mVertexArrayID);
47 mVertexArrayID = 0;
48 }
49
Geoff Lang6ae6efc2015-03-09 14:42:35 -040050 mElementArrayBuffer.set(nullptr);
Geoff Langba4c4a82015-02-24 12:38:46 -050051 for (size_t idx = 0; idx < mAppliedAttributes.size(); idx++)
52 {
53 mAppliedAttributes[idx].buffer.set(NULL);
54 }
55}
Geoff Langf9a6f082015-01-22 13:32:49 -050056
57void VertexArrayGL::setElementArrayBuffer(const gl::Buffer *buffer)
58{
Geoff Lang6ae6efc2015-03-09 14:42:35 -040059 mElementArrayBuffer.set(buffer);
60}
61
62void VertexArrayGL::setAttribute(size_t idx, const gl::VertexAttribute &attr)
63{
64 mAttributes[idx] = attr;
65}
66
67void VertexArrayGL::setAttributeDivisor(size_t idx, GLuint divisor)
68{
69 mAttributes[idx].divisor = divisor;
70}
71
72void VertexArrayGL::enableAttribute(size_t idx, bool enabledState)
73{
74 mAttributes[idx].enabled = enabledState;
75}
76
77void VertexArrayGL::syncState() const
78{
79 mStateManager->bindVertexArray(mVertexArrayID);
80
Geoff Langba4c4a82015-02-24 12:38:46 -050081 GLuint elementArrayBufferID = 0;
Geoff Lang6ae6efc2015-03-09 14:42:35 -040082 if (mElementArrayBuffer.get() != nullptr)
Geoff Langba4c4a82015-02-24 12:38:46 -050083 {
Geoff Lang6ae6efc2015-03-09 14:42:35 -040084 const BufferGL *bufferGL = GetImplAs<BufferGL>(mElementArrayBuffer.get());
Geoff Langba4c4a82015-02-24 12:38:46 -050085 elementArrayBufferID = bufferGL->getBufferID();
86 }
87
88 if (elementArrayBufferID != mAppliedElementArrayBuffer)
89 {
Geoff Langba4c4a82015-02-24 12:38:46 -050090 mStateManager->bindBuffer(GL_ELEMENT_ARRAY_BUFFER, elementArrayBufferID);
Geoff Langba4c4a82015-02-24 12:38:46 -050091 mAppliedElementArrayBuffer = elementArrayBufferID;
92 }
Geoff Langf9a6f082015-01-22 13:32:49 -050093
Geoff Lang6ae6efc2015-03-09 14:42:35 -040094 for (size_t idx = 0; idx < mAttributes.size(); idx++)
Geoff Langba4c4a82015-02-24 12:38:46 -050095 {
Geoff Lang6ae6efc2015-03-09 14:42:35 -040096 if (mAppliedAttributes[idx] != mAttributes[idx])
Geoff Langba4c4a82015-02-24 12:38:46 -050097 {
Geoff Lang6ae6efc2015-03-09 14:42:35 -040098 if (mAttributes[idx].enabled)
99 {
100 mFunctions->enableVertexAttribArray(idx);
101 }
102 else
103 {
104 mFunctions->disableVertexAttribArray(idx);
105 }
106
107 const gl::Buffer *arrayBuffer = mAttributes[idx].buffer.get();
108 if (arrayBuffer != nullptr)
109 {
110 const BufferGL *arrayBufferGL = GetImplAs<BufferGL>(arrayBuffer);
111 mStateManager->bindBuffer(GL_ARRAY_BUFFER, arrayBufferGL->getBufferID());
112 }
113 else
114 {
115 // This will take some extra work, core OpenGL doesn't support binding raw data pointers
116 // to VAOs
117 UNIMPLEMENTED();
118 }
119
120 if (mAttributes[idx].pureInteger)
121 {
122 mFunctions->vertexAttribIPointer(idx, mAttributes[idx].size, mAttributes[idx].type,
123 mAttributes[idx].stride, mAttributes[idx].pointer);
124 }
125 else
126 {
127 mFunctions->vertexAttribPointer(idx, mAttributes[idx].size, mAttributes[idx].type,
128 mAttributes[idx].normalized, mAttributes[idx].stride,
129 mAttributes[idx].pointer);
130 }
131
132 mFunctions->vertexAttribDivisor(idx, mAttributes[idx].divisor);
133
134 mAppliedAttributes[idx] = mAttributes[idx];
Geoff Langba4c4a82015-02-24 12:38:46 -0500135 }
Geoff Langba4c4a82015-02-24 12:38:46 -0500136 }
137}
138
139GLuint VertexArrayGL::getVertexArrayID() const
140{
141 return mVertexArrayID;
Geoff Langf9a6f082015-01-22 13:32:49 -0500142}
143
144}