En OpenGL, ¿puedo dibujar un píxel exactamente en las coordenadas (5, 5)?

7 minutos de lectura

avatar de usuario de xzhu
xzhu

Por (5, 5) me refiero exactamente a la quinta fila y la quinta columna.

Me resultó muy difícil dibujar cosas usando las coordenadas de la pantalla, todas las coordenadas en OpenGL son relativas y, por lo general, oscilan entre -1,0 y 1,0. ¿Por qué es tan serio evitar que los programadores usen coordenadas de pantalla/coordenadas de ventana?

  • porque usando [-1..1] en lugar de [0..800] también funcionará con una pantalla de 1024p. Pero desde conozca el tamaño de su pantalla, haga lo que dijeron datenwolf y basszero.

    – Calvin1602

    27 de mayo de 2011 a las 23:18

  • OpenGL es lo que sucede cuando los estándares informáticos son diseñados por matemáticos. Si la gente de CS y la gente de UX estuvieran presentes allí, incluirían funciones simples para establecer la resolución, el modo de texto y la capacidad de dibujar líneas finas con precisión de subpíxeles fuera de la caja.

    – anatoly techtonik

    10 de abril de 2013 a las 12:11

  • stackoverflow.com/questions/5467218/opengl-2d-hud-over-3d

    – Ciro Santilli OurBigBook.com

    12 abr 2016 a las 10:53

  • ¡Gracias! Parece que Internet guarda silencio al respecto.

    – Andrés

    1 de abril de 2017 a las 17:13

avatar de usuario de basszero
bajo cero

La forma más sencilla es probablemente configurar la proyección para que coincida con las dimensiones de píxeles del espacio de renderizado a través de glOrto. Entonces los vértices pueden estar en coordenadas de píxeles. La desventaja es que cambiar el tamaño de la ventana podría causar problemas y, en su mayoría, está desperdiciando las transformaciones aceleradas.

Suponiendo una ventana de 640×480:

// You can reverse the 0,480 arguments depending on you Y-axis 
// direction preference
glOrtho(0, 640, 0, 480, -1, 1);

Los objetos y las texturas del búfer de cuadros son otra vía, pero tendrá que crear sus propias rutinas de rasterización (dibujar líneas, círculos, mapas de bits, etc.). Hay probablemente librerías para esto.

  • Casi diez años después, pero esta debería ser la respuesta aceptada.

    – de z0rberg

    11 de diciembre de 2020 a las 19:08

Avatar de usuario de J.Guarin
J.Guarín

@ dandan78 OpenGL no es un renderizador de gráficos vectoriales. Es un Rasterizador. Y de manera más precisa se describe un Estándar por medio de una interfaz en lenguaje C. Un rasterizador, asigna objetos representados en espacios coordinados 3D (un automóvil, un árbol, una esfera, un dragón) en espacios coordinados 2D (por ejemplo, un avión, la ventana de su aplicación o su pantalla), estas coordenadas 2D pertenecen a un plano coordinado discreto. El método de representación contraria de la rasterización es Ray Tracing.

Los gráficos vectoriales son una forma de representar mediante funciones matemáticas un conjunto de curvas, líneas o primitivas geométricas similares, de forma no discreta. Entonces, los gráficos vectoriales están en el campo de “representación del modelo” en lugar del campo de “representación”.

Avatar de usuario de Christian Rau
cristian raú

Simplemente puede cambiar la “cámara” para hacer que las coordenadas 3D coincidan con las coordenadas de la pantalla configurando la matriz de vista del modelo en identidad y la proyección en una proyección ortográfica (vea mi respuesta sobre esta pregunta). Luego, puede dibujar una primitiva de un solo punto en las coordenadas de pantalla requeridas.

También puede establecer la posición de la trama con glWindowPos (que funciona en coordenadas de pantalla, a diferencia de glRasterPos) y luego simplemente use glDrawPixels para dibujar una imagen de 1×1 píxeles.

glEnable( GL_SCISSOR_TEST );
glScissor( 5, 5, 1, 1 ); /// position of pixel
glClearColor( 1.0f, 1.0f, 1.0f, 0.0f ); /// color of pixel
glClear( GL_COLOR_BUFFER_BIT );
glDisable( GL_SCISSOR_TEST );

Al cambiar los últimos 2 argumentos de glScissor, también puede dibujar un rectángulo perfecto de píxeles.

avatar de usuario de dandan78
dandan78

Hice un poco de programación 3D hace varios años y, aunque estoy lejos de ser un experto, creo que estás pasando por alto una diferencia muy importante entre el mapa de bits clásico DrawPixel(x, y) gráficos y el tipo de gráficos hechos con Direct3D y OpenGL.

En los días previos al 3D, los gráficos por computadora se trataban principalmente de mapas de bits, es decir, colecciones de puntos de colores. Estos puntos tenían una relación de 1:1 con los píxeles de su monitor.

Sin embargo, eso tenía numerosos inconvenientes, entre ellos, dificultar mucho el 3D y requerir mapas de bits de diferentes tamaños para diferentes resoluciones de pantalla.

En OpenGL/D3D, se trata de gráficos vectoriales. Las líneas se definen mediante puntos en un espacio de coordenadas tridimensional, las formas se definen mediante líneas, etc. Las superficies pueden tener texturas, se pueden agregar luces, al igual que varios tipos de efectos de iluminación, etc. Esta escena completa, o una parte de ella, se puede ver a través de una cámara virtual.

Lo que ‘ve’ a través de esta cámara virtual es una proyección de la escena en una superficie 2D. Todavía estamos tratando con gráficos vectoriales en este punto. Sin embargo, dado que las pantallas de computadora consisten en píxeles discretos, esta imagen vectorial debe rasterizarse, lo que transforma el vector en un mapa de bits con píxeles reales.

Para resumir, no puede usar coordenadas de pantalla/ventana porque OpenGL se basa en gráficos vectoriales.

  • Entonces, ¿quién rasteriza los datos vectoriales procesados ​​por OpenGL? Si es OpenGL en sí, creo que al menos debería dejar algunas API que permitan a los usuarios modificar ligeramente el resultado final, o mejor dejar una ventana que permita a los usuarios leer/escribir los búferes de píxeles.

    – xzhu

    27 de mayo de 2011 a las 11:37


  • Puede asignar un objeto de búfer de fotogramas, renderizar su escena en él y luego hacer todo el trabajo de pintura de píxeles que desee con él.

    – n0rd

    27 de mayo de 2011 a las 11:41

  • Dicho esto, es realmente fácil mapear las coordenadas de OpenGL a las coordenadas de la ventana gráfica: glViewport(win_offset_x, win_offset_y, win_width, win_height); glMatrixMode(GL_PROJECTION); glLoadIdentity(); glOrtho(win_offset_x, win_offset_x+win_width, win_offset_y, win_offset_y+win_height, -1, 1); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); et voìla, las coordenadas de OpenGL ahora se asignan a las coordenadas de píxeles de la ventana gráfica.

    – datenwolf

    27 de mayo de 2011 a las 13:28


  • Wow, ESTA fue la respuesta aceptada? Ni siquiera respondió la pregunta, solo dice: “Lo que estás tratando de hacer es imposible”, lo cual es una mentira rotunda.

    – Andrés

    1 abr 2017 a las 17:15

  • Esta respuesta y el hecho de que alguien haya votado a favor realmente me molesta.

    – Andrés

    1 abr 2017 a las 17:17

Sé que llego muy tarde a la fiesta, pero por si acaso alguien tiene esta pregunta en el futuro. Convertí las coordenadas de la pantalla a las coordenadas de la matriz OpenGL usando estas:

double converterX (double x, int window_width) {
    return 2 * (x / window_width) - 1;
}

double converterY (double y, int window_height) {
    return -2 * (y / window_height) + 1;
}

Que son básicamente métodos de reescalado.

  • Entonces, ¿quién rasteriza los datos vectoriales procesados ​​por OpenGL? Si es OpenGL en sí, creo que al menos debería dejar algunas API que permitan a los usuarios modificar ligeramente el resultado final, o mejor dejar una ventana que permita a los usuarios leer/escribir los búferes de píxeles.

    – xzhu

    27 de mayo de 2011 a las 11:37


  • Puede asignar un objeto de búfer de fotogramas, renderizar su escena en él y luego hacer todo el trabajo de pintura de píxeles que desee con él.

    – n0rd

    27 de mayo de 2011 a las 11:41

  • Dicho esto, es realmente fácil mapear las coordenadas de OpenGL a las coordenadas de la ventana gráfica: glViewport(win_offset_x, win_offset_y, win_width, win_height); glMatrixMode(GL_PROJECTION); glLoadIdentity(); glOrtho(win_offset_x, win_offset_x+win_width, win_offset_y, win_offset_y+win_height, -1, 1); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); et voìla, las coordenadas de OpenGL ahora se asignan a las coordenadas de píxeles de la ventana gráfica.

    – datenwolf

    27 de mayo de 2011 a las 13:28


  • Wow, ESTA fue la respuesta aceptada? Ni siquiera respondió la pregunta, solo dice: “Lo que estás tratando de hacer es imposible”, lo cual es una mentira rotunda.

    – Andrés

    1 abr 2017 a las 17:15

  • Esta respuesta y el hecho de que alguien haya votado a favor realmente me molesta.

    – Andrés

    1 abr 2017 a las 17:17

¿Ha sido útil esta solución?