Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to draw a single pixel in OpenGL?

Tags:

c++

opengl

glut

Can someone tell me how to draw a single white pixel at a coordinate, say (100,200)?

I am using GLUT and so far have figured out how to open a blank window. Once I figure out how to draw pixels, I will use that to implement the Bresenham line drawing algorithm. (Yes, I am aware OpenGL can draw lines. I am required to implement this myself).

#include <stdio.h>
#include <GL/glut.h>

static int win(0);

int main(int argc, char* argv[]){
    glutInit(&argc,argv);
    glutInitDisplayMode(GLUT_RGBA|GLUT_SINGLE);
    glutInitWindowSize(500,500);
    glutInitWindowPosition(100,100);

    //step 2. Open a window named "GLUT DEMO"
    win = glutCreateWindow("GLUT DEMO");
    glClearColor(0.0,0.0,0.0,0.0); //set background

    glClear(GL_COLOR_BUFFER_BIT);
    glFlush();
    glutMainLoop();
}
like image 393
quantumbutterfly Avatar asked Feb 23 '17 01:02

quantumbutterfly


3 Answers

glVertex2i(x,y);

Here is the context it needs to work:

glutInit(&argc, argv);
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);

glutInitWindowPosition(80, 80);
glutInitWindowSize(500,500);

glutCreateWindow("A Simple OpenGL Program");

glClear(GL_COLOR_BUFFER_BIT);
glMatrixMode( GL_PROJECTION );
glLoadIdentity();
gluOrtho2D( 0.0, 500.0, 500.0,0.0 );

glBegin(GL_POINTS);
   glColor3f(1,1,1);
   glVertex2i(100,100);
glEnd();
like image 111
quantumbutterfly Avatar answered Oct 19 '22 05:10

quantumbutterfly


Using modern OpenGL you can combine glScissor() with a quad that fills the entire screen.

The shaders can be as simple as:

// Vertex Shader
#version 330 core
layout (location = 0) in vec3 aPos;
void main()
{
    gl_Position = vec4(aPos.x, aPos.y, aPos.z, 1.0);
}
// Fragment Shader
#version 330 core
out vec4 FragColor;
uniform vec4 inColor;
void main()
{
    FragColor = inColor;
}

After doing OpenGL and Windows initialization with your preferred method (GLFW, GLAD, GLEN, etc.), create a quad (really two triangles) to cover the entire screen like:

float vertices[] = {
    -1.0f, -1.0f, 0.0f,
     1.0f, -1.0f, 0.0f,
     1.0f,  1.0f, 0.0f,
    -1.0f, -1.0f, 0.0f,
     1.0f,  1.0f, 0.0f,
    -1.0f,  1.0f, 0.0f
};

Then create your buffers, compile your shaders and bind your shader program and VAO.
Then use:

glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

Your drawing code would look something like this to draw a green pixel at x = 100, y = 100:

GLint transformLoc = glGetUniformLocation(shaderProgramId, "inColor");
glUniform4f(transformLoc, 0.0f, 1.0f, 0.0f, 1.0f);

glEnable(GL_SCISSOR_TEST);
glScissor(100, 100, 1, 1); // position of pixel
glDrawArrays(GL_TRIANGLES, 0, 6);
glDisable(GL_SCISSOR_TEST);

I wrote a tiny graphics rendering class built on top of OpenGL that has code doing exatly that. Its core function is putPixel(), which receives the x/y coordinates and a color to draw a single pixel on the screen. Feel free to take a look at the code: https://github.com/amengol/MinGL

like image 30
Jorge Amengol Avatar answered Oct 19 '22 03:10

Jorge Amengol


This can be done easily by setting the scissor rectangle, and then clearing, which will only clear the specified area in the scissor rectangle. For example:

glEnable(GL_SCISSOR_TEST);
glScissor(100, 200, 1, 1);
glClearColor(1,1,1,1);
glClear(GL_COLOR_BUFFER_BIT);
// Remember to disable scissor test, or, perhaps reset the scissor rectangle:
glDisable(GL_SCISSOR_TEST); 
like image 38
MuertoExcobito Avatar answered Oct 19 '22 03:10

MuertoExcobito