Ok. Got it working with perfect points by changing some stuff i just out here for analysis. In principle, as has been said, it because of different resolutions of the frame buffer and the window size.
Here's the code:
// Include GLEWf
#include <GL/glew.h>
// Include GLFW
#include <GLFW/glfw3.h>
GLFWwindow* window;
// Include GLM
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
using namespace glm;
//#include <common/shader.hpp>
#include <iostream>
#include <vector>
#include <memory>
#include "Module.h"
#include "Program.h"
const float USER_DISTANCE_MM = 440.0f; // eye to Screen
const float NEAR_MM = 100.0f;
const float FAR_MM = 1000.0f;
const float SIZE_PERCENT = 70.0f; // 100=fullScreen
using namespace orf_n;
struct Size {
float width, height; // pixels
int width_mm, height_mm;
void init(Size ref, float percent) {
float p = percent/100.0f;
width = int(ref.width * p);
height = int(ref.height * p);
width_mm = ref.width_mm * p;
height_mm = ref.height_mm * p;
}
} Screen, Window;
int main( void )
{
// Initialise GLFW
if( !glfwInit() )
{
fprintf( stderr, "Failed to initialize GLFW\n" );
getchar();
return -1;
}
glfwWindowHint(GLFW_SAMPLES, 0);
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
GLFWmonitor *monitor = glfwGetPrimaryMonitor();
const GLFWvidmode *return_struct = glfwGetVideoMode(monitor);
Screen.width = return_struct->width; Screen.height = return_struct->height;
if (Screen.width < 800 || Screen.height > 8192) {
fprintf(stderr, "Got weird display resolution %f x %f", Screen.width, Screen.height);
Screen.width = 1024; Screen.height = 576;
fprintf(stderr, "Defaulting to %f x %f", Screen.width, Screen.height);
}
/*glfwGetMonitorPhysicalSize(monitor, &Screen.width_mm, &Screen.height_mm);
if (Screen.width_mm < 120 || Screen.width_mm > 1000)
{
fprintf(stderr, "Got weird display size %d x %d mm", Screen.width_mm, Screen.height_mm);
Screen.width_mm = 345; Screen.height_mm = 194;
fprintf(stderr, "Defaulting to %d x %d mm", Screen.width_mm, Screen.height_mm);
}
Window.init(Screen, SIZE_PERCENT);*/
// Open a window and create its OpenGL context
window = glfwCreateWindow( 800, 600, "Hi !", nullptr, nullptr );
if( window == NULL ){
std::cout << "Window jammed ..." << std::endl;
glfwTerminate();
return EXIT_FAILURE;
}
glfwMakeContextCurrent(window);
// Initialize GLEW
glewExperimental = true; // Needed for core profile
if (glewInit() != GLEW_OK) {
fprintf(stderr, "Failed to initialize GLEW\n");
getchar();
glfwTerminate();
return -1;
}
// Ensure we can capture the escape key being pressed below
glfwSetInputMode(window, GLFW_STICKY_KEYS, GL_TRUE);
glfwSwapInterval( 1 );
// Black background
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
GLuint VertexArrayID;
glGenVertexArrays(1, &VertexArrayID);
glBindVertexArray(VertexArrayID);
// Create and compile our GLSL program from the shaders
std::vector<std::shared_ptr<Module>> modules;
modules.push_back( std::make_shared<Module>( GL_VERTEX_SHADER, "src/vert.glsl" ) );
modules.push_back( std::make_shared<Module>( GL_FRAGMENT_SHADER, "src/frag.glsl" ) );
Program *shaderProg = new Program( modules );
GLuint programID{ shaderProg->getProgram() };
const int NSTORE = 16384;
const int XSTART = 0*NSTORE;
const int YSTART = 1*NSTORE;
const int ZSTART = 2*NSTORE;
GLfloat g_vertexes[3*NSTORE];
GLuint vertexbuffer;
glGenBuffers(1, &vertexbuffer);
glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
//glBufferData(GL_ARRAY_BUFFER, sizeof(g_vertexes), NULL, GL_DYNAMIC_DRAW); // allocate memory on GPU
glBufferData(GL_ARRAY_BUFFER, sizeof(g_vertexes), NULL, GL_STATIC_DRAW);
GLuint MatrixID = glGetUniformLocation(programID, "MVP");
GLuint BrightnessID = glGetUniformLocation(programID, "intrinsic_brightness");
// Use our shader
glUseProgram(programID);
glUniform1f(BrightnessID, NEAR_MM*NEAR_MM); // Brightness/NEAR_MM/NEAR_MM == 1.0 = maximum brightness
glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
//glDisable(GL_POINT_SMOOTH);
//glPointSize(1); // smaller than 1 makes no difference
float rot = 0;
int i;
int fcnt=0;
const int DOFRAMES=600;
do {
// Clear the Screen
glClear( GL_COLOR_BUFFER_BIT );
// Model matrix : rotate slowly around Z axis
glm::mat4 Model = glm::rotate(glm::mat4(1.0f), rot/2, glm::vec3(0.0f,0.0f,1.0f));
// Camera matrix
glm::mat4 View = glm::lookAt(glm::vec3(0.0f,0.0f,USER_DISTANCE_MM), // Position of Camera in World Space
glm::vec3(0.0f, 0.0f, 0.0f), // What the camera is looking at
glm::vec3(0.0f,1.0f,0.0f) // Head is up
);
// Projection matrix : Vertical Field of View, square pixel ratio, display range : 100 - 1000 mm
// glm::mat4 Projection = glm::perspective(asin(Window.height_mm/2/USER_DISTANCE_MM)*2, Window.width/Window.height, NEAR_MM, FAR_MM);
glm::mat4 Projection = glm::perspective( glm::radians( 15.0f ), 800.0f/600.0f, NEAR_MM, FAR_MM);
// Our ModelViewProjection : multiplication of our 3 matrices
glm::mat4 MVP = Projection * View * Model; // Order matters
glUniformMatrix4fv(MatrixID, 1, GL_FALSE, &MVP[0][0]);
rot += 0.01f;
// Create the model: a regular 2D array of points spaced 3 mm apart
int NDRAW =0;
for (int y=-60; y<=60; y+=3 ) {
for (int x=-60; x<=60; x+=3) {
g_vertexes[XSTART+NDRAW] = x;
g_vertexes[YSTART+NDRAW] = y;
g_vertexes[ZSTART+NDRAW] = 0;
NDRAW++;
}
}
// memcpy vertex coordinates to GPU
for (i=0; i<3; i++) {
glBufferSubData(GL_ARRAY_BUFFER, i*NSTORE*sizeof(float), NDRAW*sizeof(float), &g_vertexes[i*NSTORE]);
glEnableVertexAttribArray(i);
glVertexAttribPointer(
i, // attribute 0. No particular reason for 0, but must match the layout in the shader.
1, // size
GL_FLOAT, // type
GL_FALSE, // normalized?
0, // stride
(void*)(i*NSTORE*sizeof(float)) // array buffer offset
);
}
// Draw the dots !
glDrawArrays(GL_POINTS, 0, NDRAW);
for (i=0; i<3; i++)
glDisableVertexAttribArray(i);
// Swap buffers
glfwSwapBuffers(window);
glfwPollEvents();
fcnt++;
if (fcnt==DOFRAMES) break;
} // Check if the ESC key was pressed or the window was closed
while( glfwGetKey(window, GLFW_KEY_ESCAPE ) != GLFW_PRESS
#if SIZE_PERCENT != 100
&& glfwWindowShouldClose(window) == 0
#endif
);
// Cleanup VBO
glDeleteBuffers(1, &vertexbuffer);
glDeleteVertexArrays(1, &VertexArrayID);
glDeleteProgram(programID);
// Close OpenGL window and terminate GLFW
glfwTerminate();
return 0;
}
Sorry for the c++/c chaos ... but i think you get the point (hahaha) of it: If using windowed mode, set the window size manually. Use glfw's callbacks to resize (not implemented here) and give the window sizes to the lookat/projection matrices.
n.b.: please consider doing epsilon comparisons for floating point == comparisons !
If something's unclear, just ask ?
Edit: don't be confused by the shader compiling stuff, i just copied in my routines to get it running quickly with error messages etc.
And pls. consider computing color in the shader not based on fargcoord.w, but some other calculation. Fragcoord.w is clip space position related, i think ... (?)
fragment shader code:
// float brightness = pow(intrinsic_brightness * gl_FragCoord.w * gl_FragCoord.w, 1/2.2);
float brightness = 1.0f; // do awesome colours here.