void gpuDrawVbo(u32 vbo) { VboData* vboData = (VboData*) vbo; if(vboData == NULL || vboData->data == NULL) { return; } gpuUpdateState(); static u32 attributeBufferOffset = 0; GPU_SetAttributeBuffers(vboData->attributeCount, (u32*) osConvertVirtToPhys((u32) vboData->data), vboData->attributes, vboData->attributeMask, vboData->attributePermutations, 1, &attributeBufferOffset, &vboData->attributePermutations, &vboData->attributeCount); if(vboData->indices != NULL) { GPU_DrawElements((GPU_Primitive_t) vboData->primitive, (u32*) vboData->indices, vboData->numVertices); } else { GPU_DrawArray((GPU_Primitive_t) vboData->primitive, vboData->numVertices); } }
void RectangleShape::draw() { if (!_device->isInitialized() || !_visible) return; updateTransform(); if (_color.a > 0) { ShaderProgram::setUniform(UNIFORM_MODELVIEW_NAME, getCombinedTransform()); #ifdef _3DS auto vertices = VertexPool::getInstance()-> pushVertices<VertexPositionTexture>(4); vertices[0].position = Vec2(0, 0); vertices[1].position = Vec2(_size.x, 0); vertices[2].position = Vec2(0, _size.y); vertices[3].position = Vec2(_size.x, _size.y); vertices[0].texcoord = Vec2::Zero; vertices[1].texcoord = Vec2::Zero; vertices[2].texcoord = Vec2::Zero; vertices[3].texcoord = Vec2::Zero; //========================================================================= GPU_SetTexEnv(0, GPU_TEVSOURCES(GPU_CONSTANT, GPU_CONSTANT, GPU_CONSTANT), GPU_TEVSOURCES(GPU_CONSTANT, GPU_CONSTANT, GPU_CONSTANT), GPU_TEVOPERANDS(0, 0, 0), GPU_TEVOPERANDS(0, 0, 0), GPU_REPLACE, GPU_REPLACE, _color.r | _color.g << 8 | _color.b << 16 | _color.a << 24); u32 bufferOffsets[] = { 0x00 }; u64 bufferPermutations[] = { 0x10 }; u8 bufferNumAttributes[] = { 2 }; GPU_SetAttributeBuffers( 2, (u32*)osConvertVirtToPhys((u32)vertices), GPU_ATTRIBFMT(0, 2, GPU_FLOAT) | GPU_ATTRIBFMT(1, 2, GPU_FLOAT), 0xFFFC, 0x10, 1, bufferOffsets, bufferPermutations, bufferNumAttributes); GPU_DrawArray(GPU_TRIANGLE_STRIP, 0, 4); #else Vec4 c = _color.toVector(); float vertices[] = { 0, 0, -0.5f, c.x, c.y, c.z, c.w, 0, 0, _size.x, 0, -0.5f, c.x, c.y, c.z, c.w, 0, 0, 0, _size.y, -0.5f, c.x, c.y, c.z, c.w, 0, 0, _size.x, _size.y, -0.5f, c.x, c.y, c.z, c.w, 0, 0 }; glUniform1i(ShaderProgram::getCurrentProgram()-> getUniformLocation("textureEnabled"), false); glBindBuffer(GL_ARRAY_BUFFER, _vbo); glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(float) * 36, vertices); glBindBuffer(GL_ARRAY_BUFFER, 0); glBindVertexArray(_vao); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); glBindVertexArray(0); #endif // _3DS } if (getOutlineColor().a > 0) { _outline.setTransform(getCombinedTransform()); _outline.setLine(0, 0, _size.x, 0); _outline.draw(); _outline.setLine(_size.x, 0, _size.x, _size.y); _outline.draw(); _outline.setLine(0, _size.y, _size.x, _size.y); _outline.draw(); _outline.setLine(0, 0, 0, _size.y); _outline.draw(); } Node::draw(); }
void RenderTarget::draw(const Vertex* vertices, unsigned int vertexCount, PrimitiveType type, const RenderStates& states) { // Nothing to draw? if (!vertices || (vertexCount == 0)) return; // Vertices allocated in the stack (common) can't be converted to physical address #ifndef EMULATION if (osConvertVirtToPhys((u32)vertices) == 0) { err() << "RenderTarget::draw() called with vertex array in inaccessible memory space." << std::endl; return; } #endif // GL_QUADS is unavailable on OpenGL ES if (type == Quads) { err() << "cpp3ds::Quads primitive type is not supported on OpenGL ES platforms, drawing skipped" << std::endl; return; } #define GL_QUADS 0 if (activate(true)) { // First set the persistent OpenGL states if it's the very first call if (!m_cache.glStatesSet) resetGLStates(); // Check if the vertex count is low enough so that we can pre-transform them bool useVertexCache = (vertexCount <= StatesCache::VertexCacheSize); if (useVertexCache) { // Pre-transform the vertices and store them into the vertex cache for (unsigned int i = 0; i < vertexCount; ++i) { Vertex& vertex = m_cache.vertexCache[i]; vertex.position = states.transform * vertices[i].position; vertex.color = vertices[i].color; vertex.texCoords = vertices[i].texCoords; } // Since vertices are transformed, we must use an identity transform to render them if (!m_cache.useVertexCache) applyTransform(Transform::Identity); } else { applyTransform(states.transform); } // Apply the view if (m_cache.viewChanged) applyCurrentView(); // Apply the blend mode if (states.blendMode != m_cache.lastBlendMode) applyBlendMode(states.blendMode); // Apply the texture Uint64 textureId = states.texture ? states.texture->m_cacheId : 0; if (textureId != m_cache.lastTextureId) applyTexture(states.texture); // Apply the shader if (states.shader) applyShader(states.shader); // If we pre-transform the vertices, we must use our internal vertex cache if (useVertexCache) { // ... and if we already used it previously, we don't need to set the pointers again if (!m_cache.useVertexCache) vertices = m_cache.vertexCache; else vertices = NULL; } // Setup the pointers to the vertices' components if (vertices) { #ifdef EMULATION const char* data = reinterpret_cast<const char*>(vertices); glCheck(glVertexPointer(2, GL_FLOAT, sizeof(Vertex), data + 0)); glCheck(glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(Vertex), data + 8)); // 8 = sizeof(Vector2f) glCheck(glTexCoordPointer(2, GL_FLOAT, sizeof(Vertex), data + 12)); // 12 = 8 + sizeof(Color) #else // Temorary workaround until gl3ds can get VAO gl*Pointer functions working u32 bufferOffsets[] = {0}; u64 bufferPermutations[] = {0x210}; u8 bufferAttribCounts[] = {3}; GPU_SetAttributeBuffers( 3, // number of attributes (u32*)osConvertVirtToPhys((u32)vertices), GPU_ATTRIBFMT(0, 2, GPU_FLOAT) | GPU_ATTRIBFMT(1, 4, GPU_UNSIGNED_BYTE) | GPU_ATTRIBFMT(2, 2, GPU_FLOAT), 0xFF8, //0b1100 0x210, 1, //number of buffers bufferOffsets, bufferPermutations, bufferAttribCounts // number of attributes for each buffer ); #endif } // Find the OpenGL primitive type static const GLenum modes[] = {GL_POINTS, GL_LINES, GL_LINE_STRIP, GL_TRIANGLES, GL_TRIANGLE_STRIP, GL_TRIANGLE_FAN, GL_QUADS }; GLenum mode = modes[type]; // Draw the primitives glCheck(glDrawArrays(mode, 0, vertexCount)); // Unbind the shader, if any if (states.shader) applyShader(NULL); // Update the cache m_cache.useVertexCache = useVertexCache; } }