// バインド void Figure::bind() { if (!visible) return; #ifdef USE_VAO // VAOをバインド glBindVertexArrayOES(vaoName); return; #endif // VBOをバインド // 頂点 glBindBuffer(GL_ARRAY_BUFFER, vboNames[VBO_VERTEX]); enableAttribute(ATTRIB_VERTEX); // 法線 if (hasNormals) { glBindBuffer(GL_ARRAY_BUFFER, vboNames[VBO_NORMAL]); enableAttribute(ATTRIB_NORMAL); } // テクスチャ if (hasTexture) { glBindBuffer(GL_ARRAY_BUFFER, vboNames[VBO_TEXCOORD]); enableAttribute(ATTRIB_TEXCOORD); } // ジョイント if (hasJoint) { glBindBuffer(GL_ARRAY_BUFFER, vboNames[VBO_JOINTS]); enableAttribute(ATTRIB_JOINTS); } // インデックス if (useIndex) { glBindBuffer(GL_ARRAY_BUFFER, vboNames[VBO_INDEX]); enableAttribute(ATTRIB_INDEX); } glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vboNames[VBO_ELEMENT]); }
void StelQGL1InterleavedArrayVertexBufferBackend:: draw(StelQGL1Renderer& renderer, const Mat4f& projectionMatrix, StelQGLIndexBuffer* indexBuffer) { Q_ASSERT_X(locked, Q_FUNC_INFO, "Trying to draw a vertex buffer that is not locked."); GLenum enabledAttributes [MAX_VERTEX_ATTRIBUTES]; bool usingVertexColors = false; bool usingTexturing = false; // Offset of the current attribute relative to start of a vertex in the array. int attributeOffset = 0; // Provide all vertex attributes' arrays to GL. for(int attrib = 0; attrib < attributes.count; ++attrib) { Q_ASSERT_X(attrib < MAX_VERTEX_ATTRIBUTES, Q_FUNC_INFO, "enabledAttributes array is too small to handle all vertex attributes."); const StelVertexAttribute& attribute(attributes.attributes[attrib]); if(attribute.interpretation == AttributeInterpretation_Color) { usingVertexColors = true; } const void* attributeData = vertices + attributeOffset; int stride = vertexStride; if(attribute.interpretation == AttributeInterpretation_TexCoord) { glEnable(GL_TEXTURE_2D); usingTexturing = true; } if(attribute.interpretation == AttributeInterpretation_Color) { usingVertexColors = true; } if(attribute.interpretation == AttributeInterpretation_Position && usingProjectedPositions) { // Projected positions are used within a single renderer drawVertexBufferBackend // call - we set this so any further calls with this buffer won't accidentally // use projected data from before (we don't destroy the buffer so we can // reuse it). usingProjectedPositions = false; // Using projected positions from projectedPositions vertex array. attributeData = projectedPositions; stride = 0; } // Not a position attribute, or not using projected positions, // so use the normal vertex array. enableAttribute(enabledAttributes[attrib], attribute, attributeData, stride); attributeOffset += attributeSize(attribute.type); } glMatrixMode(GL_PROJECTION); glLoadIdentity(); // Set the real openGL projection and modelview matrix to 2d orthographic projection // thus we never need to change to 2dMode from now on before drawing glMultMatrixf(projectionMatrix); glMatrixMode(GL_MODELVIEW); // If we don't have a color per vertex, we have a global color // (to keep in line with Stellarium behavior before the GL refactor) if(!usingVertexColors) { const Vec4f& color = renderer.getGlobalColor(); glColor4f(color[0], color[1], color[2], color[3]); } // Draw the vertices. if(NULL != indexBuffer) { glDrawElements(glPrimitiveType(primitiveType), indexBuffer->length(), glIndexType(indexBuffer->indexType()), indexBuffer->indices()); } else { glDrawArrays(glPrimitiveType(primitiveType), 0, vertexCount); } for(int attribute = 0; attribute < attributes.count; attribute++) { glDisableClientState(enabledAttributes[attribute]); } if(usingTexturing) { glDisable(GL_TEXTURE_2D); } }
// ビルド void Figure::build() { // LOGD("Figure::build"); // ビルド済みの場合は無視 // if (vaoName) { // return; // } // Create a vertex array object (VAO) #ifdef USE_VAO glGenVertexArraysOES(1, &vaoName); glBindVertexArrayOES(vaoName); #else vaoName = 1; #endif // 頂点 vboNames[VBO_VERTEX] = buildVBO(&vertices.front(), vertices.size() * sizeof(float), GL_ARRAY_BUFFER); enableAttribute(ATTRIB_VERTEX); // 法線 if (!normals.empty()) { vboNames[VBO_NORMAL] = buildVBO(&normals.front(), normals.size() * sizeof(float), GL_ARRAY_BUFFER); enableAttribute(ATTRIB_NORMAL); hasNormals = true; } // テクスチャ if (!textureCoords.empty()) { vboNames[VBO_TEXCOORD] = buildVBO(&textureCoords.front(), textureCoords.size() * sizeof(float), GL_ARRAY_BUFFER); enableAttribute(ATTRIB_TEXCOORD); hasTexture = true; } // ジョイント if (!jointData.empty()) { vboNames[VBO_JOINTS] = buildVBO(&jointData.front(), jointData.size() * sizeof(float), GL_ARRAY_BUFFER); enableAttribute(ATTRIB_JOINTS); hasJoint = true; } // 頂点の番号 if (useIndex) { std::vector<short> count; for (int i = 0; i < vertices.size() / 3; i++) { count.push_back(i); } vboNames[VBO_INDEX] = buildVBO(&count.front(), count.size() * sizeof(unsigned short), GL_ARRAY_BUFFER); } // インデックス enableAttribute(ATTRIB_INDEX); vboNames[VBO_ELEMENT] = buildVBO(&vertexIndexes.front(), vertexIndexes.size() * sizeof(unsigned short), GL_ELEMENT_ARRAY_BUFFER); // サイズ計算 int cnt = vertices.size()/3; float maxx = -FLT_MAX, minx = FLT_MAX; float maxy = -FLT_MAX, miny = FLT_MAX; float maxz = -FLT_MAX, minz = FLT_MAX; for (int i = 0; i < cnt; i++) { int idx = i * 3; float x = vertices[idx]; float y = vertices[idx+1]; float z = vertices[idx+2]; if (maxx < x) maxx = x; if (minx > x) minx = x; if (maxy < y) maxy = y; if (miny > y) miny = y; if (maxz < z) maxz = z; if (minz > z) minz = z; } size.x = maxx - minx; size.y = maxy - miny; size.z = maxz - minz; // LOGD("size:%f,%f,%f", size.x, size.y, size.z); // LOGD("Figure::build:end"); }