tutorial descargar actualizar opengl

descargar - opengl intel



Dibujando una lĂ­nea de ancho variable en OpenGL(Sin glLineWidth) (7)

¿Cuál es la mejor manera de dibujar una línea de ancho variable sin usar glLineWidth? ¿Dibujar un rectángulo? Varias líneas paralelas? ¿Ninguna de las anteriores?


Puedes dibujar dos triángulos:

// Draws a line between (x1,y1) - (x2,y2) with a start thickness of t1 and // end thickness t2. void DrawLine(float x1, float y1, float x2, float y2, float t1, float t2) { float angle = atan2(y2 - y1, x2 - x1); float t2sina1 = t1 / 2 * sin(angle); float t2cosa1 = t1 / 2 * cos(angle); float t2sina2 = t2 / 2 * sin(angle); float t2cosa2 = t2 / 2 * cos(angle); glBegin(GL_TRIANGLES); glVertex2f(x1 + t2sina1, y1 - t2cosa1); glVertex2f(x2 + t2sina2, y2 - t2cosa2); glVertex2f(x2 - t2sina2, y2 + t2cosa2); glVertex2f(x2 - t2sina2, y2 + t2cosa2); glVertex2f(x1 - t2sina1, y1 + t2cosa1); glVertex2f(x1 + t2sina1, y1 - t2cosa1); glEnd(); }


Suponga que sus puntos originales son (x1, y1) -> (x2, y2). Use los siguientes puntos (x1-width / 2, y1), (x1 + width / 2, y1), (x2-width / 2, y2), (x2 + width / 2, y2) para construir un rectángulo y luego use quads / tris para dibujarlo. Esta es la manera simple e ingenua. Tenga en cuenta que para anchos de línea grandes obtendrá un comportamiento de punto final extraño. Lo que realmente quiere hacer entonces son algunos cálculos inteligentes de líneas paralelas (que no deberían ser tan malos) utilizando vectores matemáticos. Por alguna razón, viene a la mente el producto punto / cruz y la proyección vectorial.


Un rectángulo (es decir, GL_QUAD o dos GL_TRIANGLES) suena como su mejor apuesta por los sonidos de la misma, no estoy seguro de poder pensar de otra manera.


Ok, qué tal esto: (Ozgar)

A / / / / . p1 / / / / D B - .p2 - - - C

Entonces, AB es width1 y CD es width2 .

Entonces,

// find line between p1 and p2 Vector p1p2 = p2 - p1 ; // find a perpendicular Vector perp = p1p2.perpendicular().normalize() // Walk from p1 to A Vector A = p1 + perp*(width1/2) Vector B = p1 - perp*(width1/2) Vector C = p2 - perp*(width2/2) Vector D = p2 - perp*(width2/2) // wind triangles Triangle( A, B, D ) Triangle( B, D, C )

Tenga en cuenta que existe un problema de bobinado CW / CCW con este algoritmo - si el perp se calcula como (-y, x) en el diagrama anterior, entonces será un bobinado CCW, si (y, -x) entonces será un bobinado CW .


Otra forma de hacerlo, si está escribiendo un rasterizador de software por casualidad, es utilizar coordenadas baricéntricas en la etapa de coloración de píxeles y píxeles de color cuando una de las coordenadas baricéntricas está cerca de 0 . Mientras más asignación hagas, más gruesas serán las líneas.


He tenido que hacer lo mismo hoy.

Para crear una línea que abarca (x1,y1) -> (x2,y2) de un width determinado, un método muy fácil es transformar un cuadrado de tamaño de unidad simple que abarca (0., -0.5) -> (1., 0.5) usando:

  1. glTranslatef(...) para moverlo a su ubicación deseada (x1,y1) ;
  2. glScalef(...) para escalarlo a la length correcta y al width deseado: use length = sqrt( (x2-x1)^2 + (y2-y1)^2 ) o cualquier otra aproximación de baja complejidad;
  3. glRotatef(...) para glRotatef(...) hacia la orientación correcta: use angle = atan2(y2-y1, x2-x1) .

El cuadrado de la unidad se crea de manera muy simple a partir de una tira de dos triángulos GL_TRIANGLE_STRIP , que se convierte en tu línea continua después de las transformaciones anteriores.

La carga aquí se coloca principalmente en OpenGL (y su hardware de gráficos) en lugar de su código de aplicación. El procedimiento anterior se convierte fácilmente en una función genérica al rodear glPushMatrix() y glPopMatrix() .


Para aquellos que buscan una buena solución para esto, este código está escrito usando LWJGL, pero se puede adaptar fácilmente a cualquier implementación de OpenGL.

import java.awt.Color; import org.lwjgl.opengl.GL11; import org.lwjgl.util.vector.Vector2f; public static void DrawThickLine(int startScreenX, int startScreenY, int endScreenX, int endScreenY, Color color, float alpha, float width) { Vector2f start = new Vector2f(startScreenX, startScreenY); Vector2f end = new Vector2f(endScreenX, endScreenY); float dx = startScreenX - endScreenX; float dy = startScreenY - endScreenY; Vector2f rightSide = new Vector2f(dy, -dx); if (rightSide.length() > 0) { rightSide.normalise(); rightSide.scale(width / 2); } Vector2f leftSide = new Vector2f(-dy, dx); if (leftSide.length() > 0) { leftSide.normalise(); leftSide.scale(width / 2); } Vector2f one = new Vector2f(); Vector2f.add(leftSide, start, one); Vector2f two = new Vector2f(); Vector2f.add(rightSide, start, two); Vector2f three = new Vector2f(); Vector2f.add(rightSide, end, three); Vector2f four = new Vector2f(); Vector2f.add(leftSide, end, four); GL11.glBegin(GL11.GL_QUADS); GL11.glColor4f(color.getRed(), color.getGreen(), color.getBlue(), alpha); GL11.glVertex3f(one.x, one.y, 0); GL11.glVertex3f(two.x, two.y, 0); GL11.glVertex3f(three.x, three.y, 0); GL11.glVertex3f(four.x, four.y, 0); GL11.glColor4f(1, 1, 1, 1); GL11.glEnd(); }