OpenGL draws only the background, the yellow point does not appear. I want to draw it with glBegin and glEnd. The coordinates are variables, because I want to move that point later. Most of the code is just GLFW initialization the function that worries me is the
draw_player function since there the draw call is contained. The Fix I stumbled upon, to use GL_POINTS instead of GL_POINT (in glBegin as argument), does not help (I continue to use it though).
#include <GLFW/glfw3.h>
//#include <stdio.h>
//coordinates
int px, py;
//My not working function
void draw_player()
{
glColor3f(1.0f, 1.0f, 0);
glPointSize(64.0f);
glBegin(GL_POINTS);
glVertex2i(px, py);
glEnd();
}
int main(int argc, char* argv[])
{
GLFWwindow* window;
if (!glfwInit())
return -1;
window = glfwCreateWindow(910, 512, "Raycast", NULL, NULL);
if (!window)
{
glfwTerminate();
return -1;
}
glfwMakeContextCurrent(window);
glClearColor(0.1f, 0.1f, 0.5f, 1.0f);
//setting the coordinates
px = 100;
py = 10;
while (!glfwWindowShouldClose(window))
{
/* Render here */
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
draw_player();
/* Swap front and back buffers */
glfwSwapBuffers(window);
/* Poll for and process events */
glfwPollEvents();
}
glfwTerminate();
return 0;
}
The coordinate (100, 10) is not in the window. You have not specified a projection matrix. Therefore, you must specify the coordinates of the point in the normalized device space (in the range [-1.0, 1.0]).
If you want to specify the coordinates in pixel units, you must define a suitable orthographic projection with glOrtho:
int main(int argc, char* argv[])
{
GLFWwindow* window;
if (!glfwInit())
return -1;
window = glfwCreateWindow(910, 512, "Raycast", NULL, NULL);
if (!window)
{
glfwTerminate();
return -1;
}
glfwMakeContextCurrent(window);
glMatrixMode(GL_PROJECTION);
glOrtho(0, 910.0, 512.0, 0.0, -1.0, 1.0);
glMatrixMode(GL_MODELVIEW);
// [...]
}
Related
The question asks to draw the rectangle when I press "r" in the keyboard. I try to write a function to draw this rectangle. The character call back function is correct and it gives me feedback that I already press "r". I don't know how to make the triangle appear. I added this line glfwSwapBuffers(window) in the function, but it's still not working. Thanks for help in advance.
#define GLEW_STATIC
#include <GL/glew.h>
#include <GLFW/glfw3.h>
#include <iostream>
#include <vector>
#include <cmath>
#include <iostream>
#define WINDOW_WIDTH 900
#define WINDOW_HEIGHT 600
float frameBuffer[WINDOW_HEIGHT][WINDOW_WIDTH][3];
bool mask[WINDOW_HEIGHT][WINDOW_WIDTH];
GLFWwindow *window;
void display()
{
glColor3f(1.0, 0.0, 0.0);
glBegin(GL_POLYGON);
glVertex2i(50, 90);
glVertex2i(100, 90);
glVertex2i(100, 150);
glVertex2i(50, 150);
glEnd();
glFlush();
}
void CharacterCallback(GLFWwindow* lWindow, unsigned int key)
{
if(char(key) == 'r')
display();
}
void Init()
{
glfwInit();
glfwWindowHint(GLFW_RESIZABLE, GL_FALSE);
window = glfwCreateWindow(WINDOW_WIDTH, WINDOW_HEIGHT, "- <xx>", NULL, NULL);
glfwMakeContextCurrent(window);
glfwSetCharCallback(window, CharacterCallback);
glewExperimental = GL_TRUE;
glewInit();
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
ClearFrameBuffer();
}
int main()
{
Init();
while (glfwWindowShouldClose(window) == 0)
{
glClear(GL_COLOR_BUFFER_BIT);
Display();
glFlush();
glfwSwapBuffers(window);
glfwPollEvents();
}
glfwTerminate();
return 0;
}
When you draw by glBegin/glEnd sequences, then each vertex coordinate is transformed by the current view matrix and current projection matrix.
When you draw a scene, then after the transformations, the coordinates of the geometry have to be in clip space respectively normalized device space. The normalized device space is a cubic volume, with the left bottom front (-1, -1, -1) and right top far (1, 1, 1). All the geometry which is in this cube is "visible" on the viewport. All the geometry which is out of this cube is clipped.
If you want to draw a scene by using window ("pixel") coordinates, then you've to setup an orthographic projection by glOrtho. At Orthographic Projection, the view space coordinates are linearly transformed to the clip space coordinates. This means orthographic projection matrix can be used to scale the view space coordinates. e.g.:
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0.0, (GLdouble)WINDOW_WIDTH, (GLdouble)WINDOW_HEIGHT, 0.0, -1.0, 1.0);
glMatrixMode(GL_MODELVIEW);
You can do this at the end of Init().
I'm using OpenGl in c++ to draw '+' symbols. My screen has a resolution of 1920x1080, but unfortunately with my method of drawing ("glBegin(GL_LINES)" ) only works on a 1080x1080 rectangle. For x > screen_height everything gets cut off. However, I can still locate text (using Glut) on the full 1920x1080 surface. Could you help me to find what setting is at fault?
I attached a code snippet. This may not compile, as I only included what is used for the drawing of the '+' symbol.
Much appreciated. Thank you in advance.
// Libraries needed for OpenGL and strings
#include <GL/glut.h>
#include <GLFW/glfw3.h>
// header file required for this cpp file
#include "window2.hxx"
int main(int argc, char *argv[])
{
// Start GLFW as main OpenGL frontend
GLFWwindow* window;
if( !glfwInit() )
{
fprintf( stderr, "Failed to initialize GLFW\n" );
exit( EXIT_FAILURE );
}
// Later upstream GLut is used for text rendering: thus also initialize GLUT (freeglut3)
glutInit(&argc, argv);
// check the resolution of the monitor and pass it to the create window function
const GLFWvidmode* mode = glfwGetVideoMode(glfwGetPrimaryMonitor());
screen_width = mode->width;
screen_height = mode->height;
window = glfwCreateWindow(screen_width , screen_height, "LearnOpenGL", glfwGetPrimaryMonitor(), NULL );
if (!window)
{
fprintf( stderr, "Failed to open GLFW window\n" );
glfwTerminate();
exit( EXIT_FAILURE );
}
glfwMakeContextCurrent(window);
glfwSwapInterval( 1 );
// set up view
glViewport( 0, 0, screen_height, screen_width );
glMatrixMode( GL_PROJECTION );
glLoadIdentity();
// see https://www.opengl.org/sdk/docs/man2/xhtml/glOrtho.xml
glOrtho(0.0,screen_height,0.0,screen_width,0.0,1.0); // this creates a canvas for 2D drawing on
x_1 = 500;
y_1 = 100;
while( !glfwWindowShouldClose(window) ) {
// Draw gears
render_loop();
// Swap buffers
glfwSwapBuffers(window);
glfwPollEvents();
} // glfw while loop
}
//OpenGL Draw function
void render_loop()
{
// white background
glClearColor ( 1.0f, 1.0f, 1.0f, 1.0f );
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glPointSize(10);
glLineWidth(1);
// push matrix
glPushMatrix();
glColor3f(0.0, 0.0, 1.0);
glBegin(GL_LINES);
glVertex2i(x_1-10,y_1);
glVertex2i(x_1+10,y_1);
glVertex2i(x_1,y_1-10);
glVertex2i(x_1,y_1+10);
glEnd();
// pop matrix
glPopMatrix();
}
I think you've got your dimensions the wrong way round:
// set up view
glViewport( 0, 0, screen_height, screen_width );
...
glOrtho(0.0,screen_height,0.0,screen_width,0.0,1.0);
Try
glViewport( 0, 0, screen_width, screen_height);
...
glOrtho(0.0,screen_width,0.0,screen_height,0.0,1.0);
I follow the code tutorial from the OpenGL programming book, but it doesn't work. It is showing white rectangle at the top left of my window. Could you please tell me what could be wrong with it?
#include<windows.h>
#include <GL/glut.h>
float yRot=0.0;
void Render()
{
//clear color and depth buffer
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();//load identity matrix
glTranslatef(0.0f,0.0f,-4.0f);//move forward 4 units
//rotate along the y-axis
glRotatef(yRot,0.0f,1.0f,0.0f);
glColor3f(0.0f,0.0f,1.0f); //blue color
glBegin(GL_POLYGON);//begin drawing of polygon
glVertex3f(-0.5f,0.5f,0.0f);//first vertex
glVertex3f(0.5f,0.5f,0.0f);//second vertex
glVertex3f(1.0f,0.0f,0.0f);//third vertex
glVertex3f(0.5f,-0.5f,0.0f);//fourth vertex
glVertex3f(-0.5f,-0.5f,0.0f);//fifth vertex
glVertex3f(-1.0f,0.0f,0.0f);//sixth vertex
glEnd();//end drawing of polygon
yRot+=0.1f;//increment the yRot variable
}
//method the reshape the entire figure.
void reshape(int x, int h){
glViewport(0,0,x,h);
}
void init()
{
glClearColor(0.0,0.0,0.2,0.8);
}
int main(int argc, char** argv)
{
glutCreateWindow("simple triangles");
glutDisplayFunc(Render);
glutReshapeFunc(reshape);
init();
glutMainLoop();
}
First of all, you're not calling glutInit(&argc, argv) in main() before all the other GLUT related calls. Second of all, you're not calling glutSwapBuffers() in Render().
Besides that you aren't changing the projection matrix, and thus don't have the same resize function as the one presented in the beginning of the tutorial.
void Resize(int width, int height)
{
glViewport(0, 0, (GLsizei)width, (GLsizei)height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45.0f, (GLfloat)width / (GLfloat)height, 1.0f, 1000.0f);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
Changing those things and your code should work.
I use freeglut to create windows, and the code goes like this:
int window1, window2;
GLfloat cube[] = {
//cube point
}
init2()
{
//init shaders...
//init vertex arrays with cube points...
}
void display2()
{
glutSetWindow(window2);
glViewport(0, 0, WIDTH, HEIGHT);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
glEnable(GL_DEPTH_TEST);
mul.use();
glm::mat4 view;
view = camera.GetViewMatrix();
glm::mat4 projection = glm::perspective(camera.Zoom, (GLfloat)WIDTH / (GLfloat)HEIGHT, 0.1f, 100.0f);
mul.setUniform("view", view);
mul.setUniform("projection", projection);
glBindVertexArray(box_vao2);
glDrawArrays(GL_QUADS, 0, 24);
glBindVertexArray(0);
glUseProgram(0);
glutSwapBuffers();
}
openwin2()
{
window2 = glutCreateWindow("win2");
init2();
glutDisplayFunc(display2);
glutReshapeFunc(reshape2);
glutIdleFunc(idle2);
}
void mouse(int button, int state, int x, int y)
{
//do something and...
openwin2();
}
int main(int argc, char **argv)
{
//glutinit...
window1 = glutCreateWindow("window1");
init();
glutDisplayFunc(display);
glutReshapeFunc(reshape);
glutMouseFunc(mouse);
glutIdleFunc(idle);
glutMainLoop();
//...
}
So, when I click and open the window2 the first time, it can display the cube I draw with vao, but if I close it and reopen it, the window does nothing, why?
Is it something about the vao?
I reuse the shader created by the previous window context, so the second window shows nothing because the shader doesn't belong to it.
I have written a simple OpenGL program in C++ that displays a line joining the center of the window to the current position of the mouse pointer.
My code is :
#ifdef __APPLE__
#include <GLUT/glut.h>
#else
#include <GL/glut.h>
#endif
#include<iostream>
using namespace std;
void passive(int,int);
void reshape(int,int);
void init(void);
void display(void);
void camera(void);
int x=3,y=3;
int main (int argc,char **argv) {
glutInit (&argc,argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_DEPTH | GLUT_RGBA);
glutInitWindowSize(1364,689);
glutInitWindowPosition(0,0);
glutCreateWindow("Sample");
init();
glutDisplayFunc(display);
glutIdleFunc(display);
glutPassiveMotionFunc(passive);
glutReshapeFunc(reshape);
glutMainLoop();
return 0;
}
void display(void) {
glClearColor (0.0,0.0,0.0,1.0);
glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
camera();
glBegin(GL_LINES);
glVertex3f(0,0,0);
glVertex3f(x,y,0);
glEnd();
glutSwapBuffers();
}
void camera(void) {
glRotatef(0.0,1.0,0.0,0.0);
glRotatef(0.0,0.0,1.0,0.0);
glTranslated(0,0,-20);
}
void init(void) {
glEnable (GL_DEPTH_TEST);
glEnable (GL_BLEND);
glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_COLOR_MATERIAL);
}
void reshape(int w, int h) {
glViewport(0,0,(GLsizei)w,(GLsizei)h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(60,(GLfloat)w/(GLfloat)h,1.0,100.0);
glMatrixMode(GL_MODELVIEW);
}
void passive(int x1,int y1) {
x=x1; y=y1;
}
The problem I am facing is that the x and y values set in the passive() function is not correctly mapped into the screen which uses perspective projection. So the line drawn is joining the center to some other coordinate outside the screen. Any modifications to the code to get it working properly?
An easy way would be to create an orthographic projection matrix and then render all of your "2D" elements (including this line, using the screen coordinates provided by glutPassiveMotionFunc).
Something like this:
void display() {
// clear
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective( ... ) // create 3D perspective projection matrix
glMatrixMode(GL_MODELVIEW);
// Render 3D content here
// Render 2D content
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(0, width, height, 0); // create 2D orthographic projection matrix with coordinate system roughly equivalent to window position
glMatrixMode(GL_MODELVIEW);
glBegin(GL_LINES);
glVertex2f( width / 2, height / 2 ); // now we can use "pixel coordinates"
glVertex2f( cursorX, cursorY );
glEnd();
...
}
Compare this to your modification of the perspective projection in your reshape method.
Obviously you'll also want to disable states that don't make sense for a "2D" rendering (like depth buffer checking, etc) but it should be pretty obvious. Take a look at this GDSE post for a discussion of how other people do this same task.