void RenderTarget::resetGLStates() { if (activate(true)) { // Make sure that GLEW is initialized priv::ensureGlewInit(); // Define the default OpenGL states glCheck(glDisable(GL_CULL_FACE)); glCheck(glDisable(GL_LIGHTING)); glCheck(glDisable(GL_DEPTH_TEST)); glCheck(glDisable(GL_ALPHA_TEST)); glCheck(glEnable(GL_TEXTURE_2D)); glCheck(glEnable(GL_BLEND)); glCheck(glMatrixMode(GL_MODELVIEW)); glCheck(glEnableClientState(GL_VERTEX_ARRAY)); glCheck(glEnableClientState(GL_COLOR_ARRAY)); glCheck(glEnableClientState(GL_TEXTURE_COORD_ARRAY)); m_cache.glStatesSet = true; // Apply the default SFML states applyBlendMode(BlendAlpha); applyTransform(Transform::Identity); applyTexture(NULL); if (Shader::isAvailable()) applyShader(NULL); m_cache.useVertexCache = false; // Set the default view setView(getView()); } }
void RenderTarget::resetGLStates() { // Check here to make sure a context change does not happen after activate(true) bool shaderAvailable = Shader::isAvailable(); if (setActive(true)) { // Make sure that extensions are initialized priv::ensureExtensionsInit(); // Make sure that the texture unit which is active is the number 0 if (GLEXT_multitexture) { glCheck(GLEXT_glClientActiveTexture(GLEXT_GL_TEXTURE0)); glCheck(GLEXT_glActiveTexture(GLEXT_GL_TEXTURE0)); } // Define the default OpenGL states glCheck(glDisable(GL_CULL_FACE)); glCheck(glDisable(GL_LIGHTING)); glCheck(glDisable(GL_DEPTH_TEST)); glCheck(glDisable(GL_ALPHA_TEST)); glCheck(glEnable(GL_TEXTURE_2D)); glCheck(glEnable(GL_BLEND)); glCheck(glMatrixMode(GL_MODELVIEW)); glCheck(glEnableClientState(GL_VERTEX_ARRAY)); glCheck(glEnableClientState(GL_COLOR_ARRAY)); glCheck(glEnableClientState(GL_TEXTURE_COORD_ARRAY)); m_cache.glStatesSet = true; // Apply the default SFML states applyBlendMode(BlendAlpha); applyTransform(Transform::Identity); applyTexture(NULL); if (shaderAvailable) applyShader(NULL); m_cache.texCoordsArrayEnabled = true; m_cache.useVertexCache = false; // Set the default view setView(getView()); } }
void RenderTarget::draw(const Vertex* vertices, std::size_t vertexCount, PrimitiveType type, const RenderStates& states) { // Nothing to draw? if (!vertices || (vertexCount == 0)) return; // GL_QUADS is unavailable on OpenGL ES #ifdef SFML_OPENGL_ES if (type == Quads) { err() << "sf::Quads primitive type is not supported on OpenGL ES platforms, drawing skipped" << std::endl; return; } #define GL_QUADS 0 #endif if (setActive(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 (std::size_t 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; } // Check if texture coordinates array is needed, and update client state accordingly bool enableTexCoordsArray = (states.texture || states.shader); if (enableTexCoordsArray != m_cache.texCoordsArrayEnabled) { if (enableTexCoordsArray) glCheck(glEnableClientState(GL_TEXTURE_COORD_ARRAY)); else glCheck(glDisableClientState(GL_TEXTURE_COORD_ARRAY)); m_cache.texCoordsArrayEnabled = enableTexCoordsArray; } // Setup the pointers to the vertices' components if (vertices) { 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)); if (enableTexCoordsArray) glCheck(glTexCoordPointer(2, GL_FLOAT, sizeof(Vertex), data + 12)); } // 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); // If the texture we used to draw belonged to a RenderTexture, then forcibly unbind that texture. // This prevents a bug where some drivers do not clear RenderTextures properly. if (states.texture && states.texture->m_fboAttachment) applyTexture(NULL); // Update the cache m_cache.useVertexCache = useVertexCache; } }
void RenderTarget::draw(const Vertex* vertices, unsigned int vertexCount, PrimitiveType type, const RenderStates& states) { // Nothing to draw? if (!vertices || (vertexCount == 0)) return; 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) { 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)); glCheck(glTexCoordPointer(2, GL_FLOAT, sizeof(Vertex), data + 12)); } // 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; } }
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; } }