blob: e66844cb9485d4254c4bc9318c09d56c624e0cb6 [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 Langba4c4a82015-02-24 12:38:46 -050012#include "libANGLE/angletypes.h"
13#include "libANGLE/renderer/gl/BufferGL.h"
14#include "libANGLE/renderer/gl/FunctionsGL.h"
15#include "libANGLE/renderer/gl/StateManagerGL.h"
Geoff Langf9a6f082015-01-22 13:32:49 -050016
17namespace rx
18{
19
Geoff Langba4c4a82015-02-24 12:38:46 -050020VertexArrayGL::VertexArrayGL(const FunctionsGL *functions, StateManagerGL *stateManager)
21 : VertexArrayImpl(),
22 mFunctions(functions),
23 mStateManager(stateManager),
24 mVertexArrayID(0),
25 mAppliedElementArrayBuffer(0),
26 mAppliedAttributes()
27{
28 ASSERT(mFunctions);
29 ASSERT(mStateManager);
30 mFunctions->genVertexArrays(1, &mVertexArrayID);
31
32 // Set the cached vertex attribute array size
33 GLint maxVertexAttribs;
34 mFunctions->getIntegerv(GL_MAX_VERTEX_ATTRIBS, &maxVertexAttribs);
35 mAppliedAttributes.resize(maxVertexAttribs);
36}
Geoff Langf9a6f082015-01-22 13:32:49 -050037
38VertexArrayGL::~VertexArrayGL()
Geoff Langba4c4a82015-02-24 12:38:46 -050039{
40 if (mVertexArrayID != 0)
41 {
42 mFunctions->deleteVertexArrays(1, &mVertexArrayID);
43 mVertexArrayID = 0;
44 }
45
46 for (size_t idx = 0; idx < mAppliedAttributes.size(); idx++)
47 {
48 mAppliedAttributes[idx].buffer.set(NULL);
49 }
50}
Geoff Langf9a6f082015-01-22 13:32:49 -050051
52void VertexArrayGL::setElementArrayBuffer(const gl::Buffer *buffer)
53{
Geoff Langba4c4a82015-02-24 12:38:46 -050054 GLuint elementArrayBufferID = 0;
55 if (buffer != nullptr)
56 {
57 const BufferGL *bufferGL = GetImplAs<BufferGL>(buffer);
58 elementArrayBufferID = bufferGL->getBufferID();
59 }
60
61 if (elementArrayBufferID != mAppliedElementArrayBuffer)
62 {
63 mStateManager->bindVertexArray(mVertexArrayID);
64 mStateManager->bindBuffer(GL_ELEMENT_ARRAY_BUFFER, elementArrayBufferID);
65 mStateManager->bindVertexArray(0);
66
67 mAppliedElementArrayBuffer = elementArrayBufferID;
68 }
Geoff Langf9a6f082015-01-22 13:32:49 -050069}
70
71void VertexArrayGL::setAttribute(size_t idx, const gl::VertexAttribute &attr)
72{
Geoff Langba4c4a82015-02-24 12:38:46 -050073 if (mAppliedAttributes[idx].type != attr.type ||
74 mAppliedAttributes[idx].size != attr.size ||
75 mAppliedAttributes[idx].normalized != attr.normalized ||
76 mAppliedAttributes[idx].pureInteger != attr.pureInteger ||
77 mAppliedAttributes[idx].stride != attr.stride ||
78 mAppliedAttributes[idx].pointer != attr.pointer ||
79 mAppliedAttributes[idx].buffer.get() != attr.buffer.get())
80 {
81 mStateManager->bindVertexArray(mVertexArrayID);
82
83 const gl::Buffer *arrayBuffer = attr.buffer.get();
84 if (arrayBuffer != nullptr)
85 {
86 const BufferGL *arrayBufferGL = GetImplAs<BufferGL>(arrayBuffer);
87 mStateManager->bindBuffer(GL_ARRAY_BUFFER, arrayBufferGL->getBufferID());
88 }
89 else
90 {
91 // This will take some extra work, core OpenGL doesn't support binding raw data pointers
92 // to VAOs
93 UNIMPLEMENTED();
94 }
95
96 if (attr.pureInteger)
97 {
98 mFunctions->vertexAttribIPointer(idx, attr.size, attr.type, attr.stride, attr.pointer);
99 }
100 else
101 {
102 mFunctions->vertexAttribPointer(idx, attr.size, attr.type, attr.normalized, attr.stride, attr.pointer);
103 }
104 mAppliedAttributes[idx].type = attr.type;
105 mAppliedAttributes[idx].size = attr.size;
106 mAppliedAttributes[idx].normalized = attr.normalized;
107 mAppliedAttributes[idx].pureInteger = attr.pureInteger;
108 mAppliedAttributes[idx].stride = attr.stride;
109 mAppliedAttributes[idx].pointer = attr.pointer;
110 mAppliedAttributes[idx].buffer.set(attr.buffer.get());
111
112 mStateManager->bindVertexArray(0);
113 }
Geoff Langf9a6f082015-01-22 13:32:49 -0500114}
115
116void VertexArrayGL::setAttributeDivisor(size_t idx, GLuint divisor)
117{
Geoff Langba4c4a82015-02-24 12:38:46 -0500118 if (mAppliedAttributes[idx].divisor != divisor)
119 {
120 mStateManager->bindVertexArray(mVertexArrayID);
121
122 mFunctions->vertexAttribDivisor(idx, divisor);
123 mAppliedAttributes[idx].divisor = divisor;
124
125 mStateManager->bindVertexArray(0);
126 }
Geoff Langf9a6f082015-01-22 13:32:49 -0500127}
128
129void VertexArrayGL::enableAttribute(size_t idx, bool enabledState)
130{
Geoff Langba4c4a82015-02-24 12:38:46 -0500131 if (mAppliedAttributes[idx].enabled != enabledState)
132 {
133 mStateManager->bindVertexArray(mVertexArrayID);
134
135 if (enabledState)
136 {
137 mFunctions->enableVertexAttribArray(idx);
138 }
139 else
140 {
141 mFunctions->disableVertexAttribArray(idx);
142 }
143 mAppliedAttributes[idx].enabled = enabledState;
144
145 mStateManager->bindVertexArray(0);
146 }
147}
148
149GLuint VertexArrayGL::getVertexArrayID() const
150{
151 return mVertexArrayID;
Geoff Langf9a6f082015-01-22 13:32:49 -0500152}
153
154}