Herramientas de usuario

Herramientas del sitio


wiki2:ogl

Diferencias

Muestra las diferencias entre dos versiones de la página.

Enlace a la vista de comparación

Ambos lados, revisión anterior Revisión previa
Próxima revisión
Revisión previa
wiki2:ogl [2015/11/28 12:07]
alfred [Asignar un color fijo en el Vertex Shader]
wiki2:ogl [2020/05/09 09:25] (actual)
Línea 22: Línea 22:
   * {{:​wiki2:​gldrawelements.simple.zip|Example}}   * {{:​wiki2:​gldrawelements.simple.zip|Example}}
  
 +==== Buffers ====
 +  * https://​open.gl/​depthstencils
 +  * https://​open.gl/​framebuffers
 +
 +==== VBO (Vertex Buffer Objects) ====
 +OpenGL ES defines the concept of buffers for exchanging data between memory areas. A buffer is a contiguous range of RAM that the graphics processor can control and manage. All the data that programs supply to the GPU should be in buffers. It doesn’t matter if a buffer stores geometric data, colors, hints for lighting effects, or other information.
 +
 +The process of creating and using VBOs (Vertex Buffer Objects) should be familiar to you because it mimics the process used for textures: first generate a ‘‘name,​’’ allocate space for the data, load the data, and then use glBindBuffer() whenever you want to use it.
 +
 +  - Generate. ''​glGenBuffers()''​. Ask OpenGL ES to generate a unique identifier for a buffer that the graphics processor controls.
 +  - Bind. ''​glBindBuffer()''​. Tell OpenGL ES to use a buffer for subsequent operations.
 +  - Buffer Data. ''​glBufferData() or glBufferSubData()''​. Tell OpenGL ES to allocate and initialize sufficient contiguous memory for a currently bound buffer—often by copying data from CPU-controlled memory into the allocated memory.
 +  - Enable or Disable. Tell OpenGL ES whether to use data in buffers during subsequent rendering.
 +  - Set Pointers. Tell OpenGL ES about the types of data in buffers and any memory offsets needed to access the data.
 +  - Draw ''​glDrawArrays() or glDrawElements()''​. Tell OpenGL ES to render all or part of a scene using data in currently bound and enabled buffers.
 +  - Delete''​glDeleteBuffers()''​. Tell OpenGL ES to delete previously generated buffers and free associated resources.
 +
 +<code objc>
 +-(void)createVBO {
 + int numXYZElements=3;​
 + int numNormalElements=3;​
 + int numColorElements=4;​
 + int numTextureCoordElements=2;​
 + long totalXYZBytes;​
 + long totalNormalBytes;​
 + long totalTexCoordinateBytes;​
 + int numBytesPerVertex;​
 +
 + // we need to generate a name for this VBO
 + glGenBuffers(1,​ &​m_VBO_SphereDataName);​
 + glBindBuffer(GL_ARRAY_BUFFER,​m_VBO_SphereDataName);​
 +
 + /* 
 + the size of each vertex in the lines 2ff. And in this case a 
 + vertex is the summation of its coordinates,​ texture coordinates,​ and
 + the normal vector, as required. The total is now multiplied by the total
 + number of vertices.
 + */
 + numBytesPerVertex=numXYZElements; ​
 + if(m_UseNormals) numBytesPerVertex+=numNormalElements;​
 + if(m_UseTexture) numBytesPerVertex+=numTextureCoordElements;​
 + numBytesPerVertex*=sizeof(GLfloat); ​
 +
 + /*
 + allocates the memory on the GPU. The final parameter is a hint to the 
 + driver saying that the data is never expected to change. If you expect ​
 + to update it, then use GL_DYNAMIC_DRAW.
 + */
 + glBufferData(GL_ARRAY_BUFFER,​ numBytesPerVertex*m_NumVertices,​ 0, GL_STATIC_DRAW);​
 +
 + /*
 + Here we use memory mapping by calling glMapBufferOES(). This
 + returns a pointer to a memory-mapped portion of the GPU’s data
 + storage inside the application’s address space. The direct method uses
 + the more traditional glBufferData().
 + */
 + GLubyte *vboBuffer=(GLubyte *)glMapBufferOES(GL_ARRAY_BUFFER,​ GL_WRITE_ONLY_OES);​
 +
 + /*
 + Now calculate the total number of bytes for each data type.
 + */
 + totalXYZBytes=numXYZElements*m_NumVertices*sizeof(GLfloat);​
 + totalNormalBytes=numNormalElements*m_NumVertices*sizeof(GLfloat);​
 + totalTexCoordinateBytes=numTextureCoordElements*m_NumVertices*sizeof(GLfloat);​
 +
 + // it is possible to copy the individual buffers one at a time by merely using memcpy()
 + memcpy(vboBuffer,​m_VertexData,​totalXYZBytes);​
 + if(m_UseNormals) {
 + vboBuffer += totalXYZBytes;​
 + memcpy(vboBuffer,​m_NormalData,​totalNormalBytes);​
 + }
 + if(m_UseTexture) {
 + vboBuffer += totalNormalBytes;​
 + memcpy(vboBuffer,​m_TexCoordsData,​totalTexCoordinateBytes);​
 + }
 +
 + // forces the actual copy action to execute
 + glUnmapBufferOES(GL_ARRAY_BUFFER);​
 + m_TotalXYZBytes=totalXYZBytes;​
 + m_TotalNormalBytes=totalNormalBytes;​
 +}
 +</​code>​
 +<code objc>
 +-(bool)renderVBO {
 + int i;
 + static int counter=0;
 + /*
 + binds it, in the same way a texture is bound. This simply makes
 + it the current object in use, until another is bound or this one is
 + unbound with glBindBuffer(GL_ARRAY_BUFFER,​ 0);.
 + */
 + glBindBuffer(GL_ARRAY_BUFFER,​ m_VBO_SphereDataName);​
 +
 + glMatrixMode(GL_MODELVIEW);​
 + glDisable(GL_CULL_FACE);​
 + glEnable(GL_BLEND);​
 + glEnable(GL_DEPTH_TEST);​
 +
 + /*
 + enable the various data buffers as has been done in previous
 + execute() methods.
 + */
 + glEnableClientState(GL_VERTEX_ARRAY);​
 + if(m_UseNormals) glEnableClientState(GL_NORMAL_ARRAY);​
 +
 + /*
 + When using VBOs, the various pointers to the data blocks are the offset ​
 + from the first element, which always starts at ‘‘address’’ of zero instead ​
 + one in the app’s own address space. So, the vertex pointer starts at address ​
 + of 0, while the normals are right after the vertices, and the texture ​
 + coordinates are right after the normals.
 + */
 + glVertexPointer(3,​GL_FLOAT,​0,​(GLvoid*)(char*)0);​
 + glNormalPointer(GL_FLOAT,​0,​(const GLvoid*)(char*)(0+m_TotalXYZBytes));​
 + glTexCoordPointer(2,​GL_FLOAT,​0,​ (const GLvoid*)((char*)(m_TotalXYZBytes+m_TotalNormalBytes)));​
 + if(m_UseTexture) {
 + if(m_TexCoordsData!=nil) {
 + glEnable(GL_TEXTURE_2D);​
 + glEnableClientState(GL_TEXTURE_COORD_ARRAY);​
 + if(m_TextureID!=0) glBindTexture(GL_TEXTURE_2D,​ m_TextureID);​
 + }
 + } else {
 + glDisableClientState(GL_TEXTURE_COORD_ARRAY);​
 + }
 +
 + /*
 + Draw
 + */
 + glDrawArrays(GL_TRIANGLE_STRIP,​ 0, (m_Slices+1)*2*(m_Stacks-1)+2);​
 + glDisable(GL_BLEND);​
 + glDisable(GL_TEXTURE_2D);​
 + return true;
 +}
 +</​code>​
 ===== Texturas ===== ===== Texturas =====
 +
 +==== Básico ====
  
 Creating textures is very similar to creating vertex buffers : Create a texture, bind it, fill it, and configure it.  Creating textures is very similar to creating vertex buffers : Create a texture, bind it, fill it, and configure it. 
Línea 45: Línea 181:
 glTexParameteri(GL_TEXTURE_2D,​ GL_TEXTURE_MIN_FILTER,​ GL_NEAREST);​ glTexParameteri(GL_TEXTURE_2D,​ GL_TEXTURE_MIN_FILTER,​ GL_NEAREST);​
 </​code>​ </​code>​
 +==== Animar texturas ====
 +=== Usando el fragment shader ===
  
 +  * {{:​wiki2:​ogl:​animating.textures.zip|}}
 +
 +==== Renderizar sobre textura ====
 +
 +Para esto se usa un FBO. Básicamente creas el FBO, reemplazas el buffer donde renderizas por el del FBO creado y dibujas, luego enlazas otra vez el buffer por defecto y en el FBO tienes la textura.
 +
 +Recuerda indicar el tamaño de píxels, haber creado anteriormente de las texturas que vas a usar en el fbo y tener el shader program activo.
 +
 +:!: Recuerda que para OpenGL el 0,0 está en la esquina de abajo a la izquierda. Si el sistema que usas cambia, es probable que **la textura fbo aparezca volteada**.
 +
 +  * {{:​wiki2:​ogl:​fbo.zip|}}
 +===== Transformaciones =====
 +
 +==== Anidar transformaciones (push y pop matrix) ====
 +
 +Para anidar transformaciones dentro de otras (al mover, escalar un elemento se mueva y escale igual el que tiene dentro), las figuras hijo aplicarán sus transformaciones a partir de la matriz del modelo de la padre.
 +
 +Es decir:
 +<code java>
 +float[] translateMatrix = new float[16];
 +setIdentityM(translateMatrix,​ 0);
 +float[] scaleMatrix = new float[16];
 +setIdentityM(scaleMatrix,​ 0);
 +
 +if (mMatrix == null) {
 +    // Si no tiene padre inicializamos la matriz del modelo a la identidad
 +    setIdentityM(modelMatrix,​ 0);
 +} else {
 +    // Si tiene padre usamos su matriz de modelo para aplicar las nuevas transformaciones
 +    for (int i = 0; i < 16; i++)
 +        modelMatrix[i] = mMatrix[i];
 +}
 +
 +// Creamos nuestras transformaciones
 +translateM(translateMatrix,​ 0, posX, posY, posZ);
 +scaleM(scaleMatrix,​ 0, sizeX, sizeY, sizeZ);
 +
 +float[] temp = new float[16];
 +
 +// Aplicamos las transformaciones sobre la matriz del modelo (anterior o identidad)
 +multiplyMM(temp,​ 0, modelMatrix,​ 0, translateMatrix,​ 0);
 +for (int i = 0; i < 16; i++)
 +    modelMatrix[i] = temp[i];
 +
 +multiplyMM(temp,​ 0, modelMatrix,​ 0, scaleMatrix,​ 0);
 +for (int i = 0; i < 16; i++)
 +    modelMatrix[i] = temp[i];
 +</​code>​
 +  * {{:​wiki2:​ogl:​nested.transforms.zip|}}
 ===== Lenguaje GLSL ===== ===== Lenguaje GLSL =====
  
Línea 163: Línea 350:
 </​code>​ </​code>​
 ===== Shaders en general ===== ===== Shaders en general =====
 +
 +  * :!: El optimizador de GLSL borrará todas las variables que no uses.
 ===== Vertex Shader ===== ===== Vertex Shader =====
 ==== Cambiar el tamaño de los puntos dibujados ==== ==== Cambiar el tamaño de los puntos dibujados ====
Línea 174: Línea 363:
 </​code>​ </​code>​
  
 +==== Hacer el color algo más oscuro ====
 +<​code>​
 +gl_FragColor = texture2D(u_TextureUnit,​ v_TextureCoordinates) * vec4(0.5, 0.5, 0.5, 1);
 +</​code>​
 ===== Otros ===== ===== Otros =====
 ==== Código ejemplo iOS ==== ==== Código ejemplo iOS ====
wiki2/ogl.1448712456.txt.gz · Última modificación: 2020/05/09 09:24 (editor externo)