una tortuga tecnunlogo sirve rectangulo que primitivas para libreria glfrustum dibujar coordenadas animacion opengl

tortuga - ¿Cómo se hacen primitivas como wireframes en OpenGL?



rectangulo opengl (8)

De http://cone3d.gamedev.net/cgi-bin/index.pl?page=tutorials/ogladv/tut5

// Turn on wireframe mode glPolygonMode(GL_FRONT, GL_LINE); glPolygonMode(GL_BACK, GL_LINE); // Draw the box DrawBox(); // Turn off wireframe mode glPolygonMode(GL_FRONT, GL_FILL); glPolygonMode(GL_BACK, GL_FILL);

¿Cómo se hacen primitivas como wireframes en OpenGL?


En Modern OpenGL (OpenGL 3.2 y superior), podrías usar un Geometry Shader para esto:

#version 330 layout (triangles) in; layout (line_strip /*for lines, use "points" for points*/, max_vertices=3) out; in vec2 texcoords_pass[]; //Texcoords from Vertex Shader in vec3 normals_pass[]; //Normals from Vertex Shader out vec3 normals; //Normals for Fragment Shader out vec2 texcoords; //Texcoords for Fragment Shader void main(void) { int i; for (i = 0; i < gl_in.length(); i++) { texcoords=texcoords_pass[i]; //Pass through normals=normals_pass[i]; //Pass through gl_Position = gl_in[i].gl_Position; //Pass through EmitVertex(); } EndPrimitive(); }

Avisos:


La forma más fácil es dibujar los primitivos como GL_LINE_STRIP .

glBegin(GL_LINE_STRIP); /* Draw vertices here */ glEnd();


Puedes usar las bibliotecas de glut de esta manera:

  1. para una esfera:

    glutWireSphere(radius,20,20);

  2. para un cilindro:

    GLUquadric *quadratic = gluNewQuadric(); gluQuadricDrawStyle(quadratic,GLU_LINE); gluCylinder(quadratic,1,1,1,12,1);

  3. para un cubo:

    glutWireCube(1.5);


Si está utilizando la canalización fija (OpenGL <3.3) o el perfil de compatibilidad que puede usar

//Turn on wireframe mode glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); //Draw the scene with polygons as lines (wireframe) renderScene(); //Turn off wireframe mode glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);

En este caso, puede cambiar el ancho de línea llamando a glLineWidth

De lo contrario, debe cambiar el modo de polígono dentro de su método de dibujo (glDrawElements, glDrawArrays, etc.) y puede obtener algunos resultados aproximados porque sus datos de vértice son para triángulos y está generando líneas. Para obtener los mejores resultados, considere usar un sombreador de geometría o crear nuevos datos para la estructura alámbrica.


Si se trata de OpenGL ES 2.0 , puede elegir una de las constantes de modo de dibujo de

GL_LINE_STRIP, GL_LINE_LOOP, GL_LINES, para dibujar líneas,

GL_POINTS (si solo necesitas dibujar vértices), o

GL_TRIANGLE_STRIP , GL_TRIANGLE_FAN y GL_TRIANGLES para dibujar triángulos rellenos

como primer argumento a tu

glDrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid * indices)

o

glDrawArrays(GLenum mode, GLint first, GLsizei count) llamadas.


Suponiendo un contexto compatible con versiones posteriores en OpenGL 3 y superior, puede usar glPolygonMode como se mencionó anteriormente, pero tenga en cuenta que las líneas con grosor de más de 1px ahora están en desuso. Entonces, si bien puedes dibujar triángulos como armazón de alambre, deben ser muy finos. En OpenGL ES, puedes usar GL_LINES con la misma limitación.

En OpenGL es posible usar sombreadores de geometría para tomar los triángulos entrantes, desmontarlos y enviarlos para la rasterización como quads (pares de triángulos realmente) emulando líneas gruesas. Bastante simple, en realidad, excepto que los sombreadores de geometría son notorios por escalabilidad de rendimiento pobre.

Lo que puede hacer en su lugar, y lo que también funcionará en OpenGL ES es emplear el sombreado de fragmentos . Piensa en aplicar una textura de triángulo de alambre al triángulo. Excepto que no se necesita textura, se puede generar de manera procesal. Pero basta de hablar, vamos a codificar. Sombreador de fragmentos:

in vec3 v_barycentric; // barycentric coordinate inside the triangle uniform float f_thickness; // thickness of the rendered lines void main() { float f_closest_edge = min(v_barycentric.x, min(v_barycentric.y, v_barycentric.z)); // see to which edge this pixel is the closest float f_width = fwidth(f_closest_edge); // calculate derivative (divide f_thickness by this to have the line width constant in screen-space) float f_alpha = smoothstep(f_thickness, f_thickness + f_width, f_closest_edge); // calculate alpha gl_FragColor = vec4(vec3(.0), f_alpha); }

Y sombreador de vértice:

in vec4 v_pos; // position of the vertices in vec3 v_bc; // barycentric coordinate inside the triangle out vec3 v_barycentric; // barycentric coordinate inside the triangle uniform mat4 t_mvp; // modeview-projection matrix void main() { gl_Position = t_mvp * v_pos; v_barycentric = v_bc; // just pass it on }

Aquí, las coordenadas baricéntricas son simplemente (1, 0, 0) , (0, 1, 0) y (0, 0, 1) para los tres vértices de triángulos (el orden no importa realmente, lo que hace que el empacamiento en tiras de triángulos sea potencialmente más fácil).

La desventaja obvia de este enfoque es que consumirá algunas coordenadas de textura y usted necesita modificar su matriz de vértices. Podría resolverse con un sombreador de geometría muy simple, pero aún sospecharía que será más lento que simplemente alimentar a la GPU con más datos.


glPolygonMode( GL_FRONT_AND_BACK, GL_LINE );

encender,

glPolygonMode( GL_FRONT_AND_BACK, GL_FILL );

para volver a la normalidad.

Tenga en cuenta que cosas como el mapeado de texturas y la iluminación aún se aplicarán a las líneas de alambre si están habilitadas, lo que puede parecer extraño.