According to a book I'm reading, vertex and fragment shaders are required for the newest versions of OpenGL, and if they're not provided, rendering will not happen properly.
I'm using the GLFW library (3.0.4), and in the spinning triangle Hello World type example, there is no code to load the GPU with these shaders. I cannot find anything that says whether GLFW provides default shaders or not...
Below is the example code I'm referring to. There are calls to glColor3f(), which might be involved.
Also, I notice that the OpenGL.org documentation doesn't seem to list glColor*() at all! Why is this?
#include "GLFW\glfw3.h"
static void error_callback(int error, const char* description)
{
fputs(description, stderr);
}
static void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods)
{
if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS)
glfwSetWindowShouldClose(window, GL_TRUE);
}
int main(void)
{
GLFWwindow* window;
glfwSetErrorCallback(error_callback);
if (!glfwInit())
exit(EXIT_FAILURE);
window = glfwCreateWindow(640, 480, "Simple example", NULL, NULL);
if (!window)
{
glfwTerminate();
exit(EXIT_FAILURE);
}
glfwMakeContextCurrent(window);
glfwSetKeyCallback(window, key_callback);
while (!glfwWindowShouldClose(window))
{
float ratio;
int width, height;
glfwGetFramebufferSize(window, &width, &height);
ratio = width / (float)height;
glViewport(0, 0, width, height);
glClear(GL_COLOR_BUFFER_BIT);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(-ratio, ratio, -1.f, 1.f, 1.f, -1.f);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glRotatef((float)glfwGetTime() * 50.f, 0.f, 0.f, 1.f);
glBegin(GL_TRIANGLES);
glColor3f(1.f, 0.f, 0.f);
glVertex3f(-0.6f, -0.4f, 0.f);
glColor3f(0.f, 1.f, 0.f);
glVertex3f(0.6f, -0.4f, 0.f);
glColor3f(0.f, 0.f, 1.f);
glVertex3f(0.f, 0.6f, 0.f);
glEnd();
glfwSwapBuffers(window);
glfwPollEvents();
}
glfwDestroyWindow(window);
glfwTerminate();
exit(EXIT_SUCCESS);
}
glBegin and glEnd indicate you use immediate mode aka the fixed function pipeline which predates shaders. That pipeline is also outdated and removed from 4.0+ core profiles.
Related
I am trying to get started with openGL and GLFW in c++. My expectation is that the following code will simply render a square on the screen, but I just get a black screen.
The actual setup is working though, because if I add glClearColor(0.1f, 0.4f, 0.8f, 1.0f);, I do indeed get a blue screen. But what is wrong with my use of GL_QUADS?
#include <iostream>
// GLEW
#define GLEW_STATIC
#include <GL/glew.h>
//GLFW
#include <GLFW/glfw3.h>
const GLint WIDTH = 800, HEIGHT = 600;
int main() {
glfwInit();
glfwWindowHint( GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint( GLFW_CONTEXT_VERSION_MINOR, 3);
glfwWindowHint( GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
glfwWindowHint( GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
glfwWindowHint( GLFW_RESIZABLE, GL_TRUE);
GLFWwindow *window = glfwCreateWindow(WIDTH, HEIGHT, "Isosurface Stuffing", nullptr, nullptr);
int screenWidth, screenHeight;
glfwGetFramebufferSize(window, &screenWidth, &screenHeight);
if (window == nullptr) {
std::cout << "Failed to create GLFW window" << std::endl;
glfwTerminate();
return -1;
}
glfwMakeContextCurrent(window);
glewExperimental = GL_TRUE;
if (GLEW_OK != glewInit()) {
std::cout << "Failed to create GLEW" << std::endl;
return -1;
}
while (!glfwWindowShouldClose(window)) {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
glViewport(0, 0, screenWidth, screenHeight);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0.0f, screenWidth, 0.0f, screenHeight, 0.0f, 1.0f);
glMatrixMode (GL_MODELVIEW);
glLoadIdentity();
glfwPollEvents();
glColor3f(0.5f, 0.5f, 0.5f);
glBegin(GL_QUADS);
glVertex2f(100, 100);
glVertex2f(200, 100);
glVertex2f(200, 200);
glVertex2f(100, 200);
glEnd();
glfwSwapBuffers(window);
}
glfwTerminate();
return 0;
}
You cannot use the legacy fixed-function pipeline instructions (glBegin, glEnd, glVertex2f, glMatrixMode, glLoadIdentity, glOrtho) in a Core profile OpenGL context (GLFW_OPENGL_CORE_PROFILE). You have to use Compatibility profile OpenGL Context:
glfwWindowHint( GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_COMPAT_PROFILE);
If your system does not allow you to create a compatibility profile context (e.g. Mac), you must use either an OpenGL 2.0 context or a modern OpenGL with Shaders and Vertex Array Objects. A nice tutorial for that is LearnOpenGL
I am trying to set the background color to blue, but glClearColor is completely ignored.
Code:
glfwWindowHint(GLFW_RESIZABLE, GL_FALSE);
GLFWwindow* window = glfwCreateWindow(640, 480, "3D Shooter", NULL, NULL);
glClearColor(0.5f, 0.5f, 1.0f, 1.0f);
while (!glfwWindowShouldClose(window)) {
glClear(GL_COLOR_BUFFER_BIT);
glfwSwapBuffers(window);
glfwPollEvents();
}
You seem to be missing a
glfwMakeContextCurrent(window);
https://www.glfw.org/docs/3.3/quick.html
I am writing a game engine in OpenGL and GLFW. However, somehow my window can't be closed. I tried many things but it doesn't have effect. What's wrong with my code?
I can't find the wrong thing in it - everything seems fine to me.
Code:
int running;
GLFWwindow* window;
Window::~Window()
{
glfwTerminate();
}
Window::Window(int width, int height, const std::string& title)
: m_width(width),
m_height(height),
m_title(title){
glfwInit();
if (!glfwInit())
glfwWindowHint(GLFW_RESIZABLE, GL_FALSE);
window = glfwCreateWindow(height, width, __FILE__, NULL, NULL);
if (!window) {
glfwTerminate();
}
running = true;
}
void Window::MainLoop()
{
do
{
glfwMakeContextCurrent(window);
glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
glFlush();
glfwPollEvents();
Draw();
glfwSwapBuffers(window);
}
while(running);
}
void Window::Draw()
{
glBegin(GL_TRIANGLES);
glVertex3f( 0.0f, 1.0f, 0.0f);
glVertex3f( 1.0f,-1.0f, 0.0f);
glVertex3f(-1.0f,-1.0f, 0.0f);
glEnd();
}
Thanks!
There are several things but the issue seems to be that you never set running = false.
Try making your while condition looking like this while(!glfwWindowShouldClose(window));
Also if you would like to be able to close the window by pressing escape this should work: while(!glfwWindowShouldClose(window) && glfwGetKey(window_, GLFW_KEY_ESCAPE) != GLFW_PRESS);
Also consider making your int running a bool.
And things such as glfwMakeContextCurrent(window); and glClearColor(0.2f, 0.3f, 0.3f, 1.0f); do not need to be inside your loop if you do not intend to change them.
For more information about openGL and to gain some basic understanding and working examples consider reading https://learnopengl.com/.
I am working through a book on OpenGL, and I am stuck on the third chapter. The following code should open a window and draw a single dot in the center.
The window shows up, glClearColor and glClear seem to be working, but no dot. This answer leads me do believe I may need to compile and link simple vertex and fragment shaders.
The book has made no mention of them, but do I need shaders? Am I missing something else with how I am drawing the dot? Something with the window? The book uses some WIN32 thing for windowing, I am using Linux Mint 17.1
Code below:
#include <stdlib.h>
#include <stdio.h>
#include <GL/glew.h>
#include <GL/gl.h>
#include <GLFW/glfw3.h>
#include <GL/glut.h>
#define BUFFER_OFFSET(i) ( (char*)NULL + (i) )
static void error_callback(int error, const char* description) {
fputs(description, stderr);
}
static void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods) {
if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS)
glfwSetWindowShouldClose(window, GL_TRUE);
}
int main(void) {
GLFWwindow* window;
glfwSetErrorCallback(error_callback);
if (!glfwInit()) {
exit(EXIT_FAILURE);
}
window = glfwCreateWindow(640, 480, "Simple example", NULL, NULL);
if (!window) {
glfwTerminate();
exit(EXIT_FAILURE);
}
glfwMakeContextCurrent(window);
glfwSwapInterval(1);
glfwSetKeyCallback(window, key_callback);
if (glewInit()) {
glfwTerminate();
exit(EXIT_FAILURE);
}
glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
float ratio;
int width, height;
glfwGetFramebufferSize(window, &width, &height);
ratio = width / (float) height;
glViewport(0, 0, width, height);
GLfloat vertex [] = {0.0f, 0.0f, -2.0f};
GLuint m_vertexBuffer;
glGenBuffers(1, &m_vertexBuffer);
glBindBuffer(GL_ARRAY_BUFFER, m_vertexBuffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * 3, &vertex[0], GL_STATIC_DRAW);
while (!glfwWindowShouldClose(window)) {
glClear(GL_COLOR_BUFFER_BIT);
glBindBuffer(GL_ARRAY_BUFFER, m_vertexBuffer);
glVertexPointer(3, GL_FLOAT, 0, BUFFER_OFFSET(0));
glPointSize(10.0f);
glEnableClientState(GL_VERTEX_ARRAY);
glDrawArrays(GL_POINTS, 0, 1);
glDisableClientState(GL_VERTEX_ARRAY);
glfwSwapBuffers(window);
glfwPollEvents();
}
glfwDestroyWindow(window);
glfwTerminate();
exit(EXIT_SUCCESS);
}
Also, I am compiling with g++ main.cpp -lGL -lglfw -lGLU -lGLEW
I have OpenGL 4.5 installed, but am opening a fixed-pipeline context.
From your code:
GLfloat vertex [] = {0.0f, 0.0f, -2.0f};
Since you use the fixed function pipelione and never set any matrices, both the projection and the modelView matrix will be left at the default, and the point (0, 0, -2) is outside fo the viewing volume. Try (0, 0, 0) instead.
If the book uses excatly this code with exactly that vertex coordinates, you'd better search for another one. You should also consider learning "modern" GL instead. The fixed-funciton pipeline basically has been superseeded by shaders in GL2.0 a decade ago.
I'm a beginner of OpenGL. After configuring the develop environment on Windows 7 64-bit, use vs2012, There's no effect when I run the demo program from gflw website.
here the code
void runRenderLoop(GLFWwindow *window){
glfwMakeContextCurrent(window);
glfwSwapInterval(1);
glfwSetKeyCallback(window,keyCallback);
while (!glfwWindowShouldClose(window)) {
int width;
int height;
glfwGetFramebufferSize(window,&width,&height);
glViewport(0,0,width,height);
glClear(GL_COLOR_BUFFER_BIT);
GLfloat ratio = static_cast<GLfloat>(width)/static_cast<GLfloat>(height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(-ratio, ratio, -1.f, 1.f, 1.f, -1.f);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glRotatef((float) glfwGetTime() * 50.f, 0.f, 0.f, 1.f);
glBegin(GL_TRIANGLES);
glColor3f(1.f, 0.f, 0.f);
glVertex3f(-0.6f, -0.4f, 0.f);
glColor3f(0.f, 1.f, 0.f);
glVertex3f(0.6f, -0.4f, 0.f);
glColor3f(0.f, 0.f, 1.f);
glVertex3f(0.f, 0.6f, 0.f);
glEnd();
glfwSwapBuffers(window);
glfwPollEvents();
}
glfwMakeContextCurrent(NULL);
glfwDestroyWindow(window);
glfwTerminate();
}
What weird is, i can see the window is created properly, also when i attach a break point between glBegin() and glEnd(), it triggers correctly. Also, glfw handles my keyCallback perfectly. However, the window is totally dark, nothing there. It really confused me
My current opengl version is 3.2
My current opengl version is 3.2
If that's a core profile context (no compatibility) then glBegin / glEnd and friends are invalid to use: They've been removed from OpenGL-3 core and later.