I use SFML to create the window.
In this screenshot the cube should be behind the pyramid but it just doesn't work.
Here is the minimal code I used:
#include <OpenGL/gl.h>
#include <OpenGL/glu.h>
#include <SFML/Graphics.hpp>
#include "ResourcePath.hpp"
void resize();
void drawScene();
void initGL();
float rtri = 0;
float rquad = 0;
float z = -10.0f;
int main (int argc, const char * argv[])
{
// Create the main window
sf::RenderWindow *window = new sf::RenderWindow();
window->Create( sf::VideoMode( 800, 600, 32 ), "Collision Detection", sf::Style::Close );
sf::Event event;
bool run = true;
initGL();
resize();
while( run ) {
window->PollEvent( event );
if( event.Type == sf::Event::Closed ) {
run = false;
}
drawScene();
window->Display();
// z+= 0.001f;
}
return EXIT_SUCCESS;
}
void resize() {
glViewport(0,0, 800,600);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
// Calculate The Aspect Ratio Of The Window
gluPerspective(45.0f,800/600,0.1f,100.0f);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
void drawScene() {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Clear Screen And Depth Buffer
glLoadIdentity(); // Reset The Current Modelview Matrix
glTranslatef(0.0f,0.0f,-6.0f); // Move Left 1.5 Units And Into The Screen 6.0
glRotatef(rtri,0.0f,1.0f,0.0f); // Rotate The Triangle On The Y axis ( NEW )
glBegin(GL_TRIANGLES);
glColor3f(1.0f,0.0f,0.0f);
glVertex3f( 0.0f, 1.0f, 0.0f);
glColor3f(0.0f,1.0f,0.0f);
glVertex3f(-1.0f,-1.0f, 1.0f);
glColor3f(0.0f,0.0f,1.0f);
glVertex3f( 1.0f,-1.0f, 1.0f);
glColor3f(1.0f,0.0f,0.0f);
glVertex3f( 0.0f, 1.0f, 0.0f);
glColor3f(0.0f,0.0f,1.0f);
glVertex3f( 1.0f,-1.0f, 1.0f);
glColor3f(0.0f,1.0f,0.0f);
glVertex3f( 1.0f,-1.0f, -1.0f);
glColor3f(1.0f,0.0f,0.0f);
glVertex3f( 0.0f, 1.0f, 0.0f);
glColor3f(0.0f,1.0f,0.0f);
glVertex3f( 1.0f,-1.0f, -1.0f);
glColor3f(0.0f,0.0f,1.0f);
glVertex3f(-1.0f,-1.0f, -1.0f);
glColor3f(1.0f,0.0f,0.0f);
glVertex3f( 0.0f, 1.0f, 0.0f);
glColor3f(0.0f,0.0f,1.0f);
glVertex3f(-1.0f,-1.0f,-1.0f);
glColor3f(0.0f,1.0f,0.0f);
glVertex3f(-1.0f,-1.0f, 1.0f);
glEnd();
glLoadIdentity(); // Reset The Current Modelview Matrix
glTranslatef(0.0f,0.0f,z); // Move Right 1.5 Units And Into The Screen 7.0
glRotatef(rquad,1.0f,1.0f,z); // Rotate The Quad On The X axis ( NEW )
glBegin(GL_QUADS);
glColor3f(0.0f,1.0f,0.0f);
glVertex3f( 1.0f, 1.0f,-1.0f);
glVertex3f(-1.0f, 1.0f,-1.0f);
glVertex3f(-1.0f, 1.0f, 1.0f);
glVertex3f( 1.0f, 1.0f, 1.0f);
glColor3f(1.0f,0.5f,0.0f);
glVertex3f( 1.0f,-1.0f, 1.0f);
glVertex3f(-1.0f,-1.0f, 1.0f);
glVertex3f(-1.0f,-1.0f,-1.0f);
glVertex3f( 1.0f,-1.0f,-1.0f);
glColor3f(1.0f,0.0f,0.0f);
glVertex3f( 1.0f, 1.0f, 1.0f);
glVertex3f(-1.0f, 1.0f, 1.0f);
glVertex3f(-1.0f,-1.0f, 1.0f);
glVertex3f( 1.0f,-1.0f, 1.0f);
glColor3f(1.0f,1.0f,0.0f);
glVertex3f( 1.0f,-1.0f,-1.0f);
glVertex3f(-1.0f,-1.0f,-1.0f);
glVertex3f(-1.0f, 1.0f,-1.0f);
glVertex3f( 1.0f, 1.0f,-1.0f);
glColor3f(0.0f,0.0f,1.0f);
glVertex3f(-1.0f, 1.0f, 1.0f);
glVertex3f(-1.0f, 1.0f,-1.0f);
glVertex3f(-1.0f,-1.0f,-1.0f);
glVertex3f(-1.0f,-1.0f, 1.0f);
glColor3f(1.0f,0.0f,1.0f);
glVertex3f( 1.0f, 1.0f,-1.0f);
glVertex3f( 1.0f, 1.0f, 1.0f);
glVertex3f( 1.0f,-1.0f, 1.0f);
glVertex3f( 1.0f,-1.0f,-1.0f);
glEnd(); // Done Drawing The Quad
rtri+=0.2f; // Increase The Rotation Variable For The Triangle ( NEW )
rquad-=0.15f;
z-=0.01;
}
void initGL() {
glShadeModel(GL_SMOOTH); // Enable Smooth Shading
glClearColor(0.0f, 0.0f, 0.0f, 0.5f); // Black Background
glClearDepth(1.0f); // Depth Buffer Setup
glEnable(GL_DEPTH_TEST); // Enables Depth Testing
glDepthFunc(GL_LEQUAL); // The Type Of Depth Testing To Do
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
glEnable( GL_CULL_FACE );
/* Position the camera */
glTranslatef(0, 0, -5);
}
I've tried different depth functions, GL_LESS, GL_EQUAL, I've tried them all. Also enabling and disabling depth testing on different places, nothing seems to work.
I'm running Mac OS X 10.7 ( Lion ), not sure if that is important, though I didn't seem to have any trouble with these kind of things before upgrading.
Your code looks okay. I suspect that your window simply does not have a depth buffer. You're using sf::RenderWindow, whose documentation says (emphasis mine):
Simple wrapper for sf::Window that allows easy 2D rendering.
I don't know SFML, but this tutorial suggests to create your window like this:
sf::WindowSettings Settings;
Settings.DepthBits = 24; // Request a 24 bits depth buffer
Settings.StencilBits = 8; // Request a 8 bits stencil buffer
Settings.AntialiasingLevel = 2; // Request 2 levels of antialiasing
sf::Window App(sf::VideoMode(800, 600, 32), "SFML OpenGL", sf::Style::Close, Settings);
You could set StencilBits and AntialiasingLevel to 0 since this example doesn't need them.
In latest version of SFML WindowSettings replaced by ContextSettings. Depth settings can be configured as.
//Configuring SFML window
sf::ContextSettings window_settings;
window_settings.depthBits = 24; // Request a 24-bit depth buffer
window_settings.stencilBits = 8; // Request a 8 bits stencil buffer
window_settings.antialiasingLevel = 2; // Request 2 levels of antialiasing
// Opening SFML window
sf::Window window(sf::VideoMode(800, 600), "Title", sf::Style::Resize | sf::Style::Close, window_settings);
glewExperimental = GL_TRUE;
// Initializing glew and openGL
glewInit();
glViewport(0, 0, 800, 600);
// Enabling Depth
glEnable(GL_DEPTH_TEST);
Related
I tried to write an "Engine" to render shapes using OpenGL.
The idea is that you can write "renderers" which are just functions that render shapes and add them to a list for the Engine class to display.
So I added a cube and a pyramid (the code for which I just copied from the internet) - and I made them rotate.
As you can see in the images at the bottom of the question - the shapes acted weird - you could see the back of the shape from the front, etc.
Now, I understand that OpenGL just renders stuff in the order I tell it to render them - causing things that are written first to be rendered first - but I used the glDepthFunc which should make it such that stuff renders by "depth" and not order of writing.
#include <GL/glut.h>
#include <iostream>
#include <list>
namespace Graphics
{
class Engine
{
public:
static void Init();
static void Display();
static void Reshape(GLsizei width, GLsizei height);
static void Timer(int value);
static bool Run(int argc, char** argv);
// A renderer is just a method that does stuff and return a boolean
using renderer_t = bool(*)();
static void AddRenderer(renderer_t renderer);
private:
static std::list<renderer_t> renderers;
};
}
namespace Graphics
{
std::list<Engine::renderer_t> Engine::renderers;
void Engine::Init()
{
glClearColor(0.0f, 0.0f, 0.0f, 1.0f); // Set background color to black and opaque
glClearDepth(1.0f); // Set background depth to farthest
glEnable(GL_DEPTH_TEST); // Enable depth testing for z-culling
glDepthFunc(GL_LEQUAL); // Set the type of depth-test
glShadeModel(GL_SMOOTH); // Enable smooth shading
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); // Nice perspective corrections
}
void Engine::Display()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Clear color and depth buffers
glMatrixMode(GL_MODELVIEW); // To operate on model-view matrix
for (auto renderer : Engine::renderers)
{
if (!renderer())
{
std::cout << "A renderer has failed rendering something... :(" << std::endl;
}
}
glutSwapBuffers(); // Swap the front and back frame buffers (double buffering)
}
void Engine::Reshape(GLsizei width, GLsizei height)
{ // GLsizei for non-negative integer
// Compute aspect ratio of the new window
if (height == 0) height = 1; // To prevent divide by 0
GLfloat aspect = (GLfloat)width / (GLfloat)height;
// Set the viewport to cover the new window
glViewport(0, 0, width, height);
// Set the aspect ratio of the clipping volume to match the viewport
glMatrixMode(GL_PROJECTION); // To operate on the Projection matrix
glLoadIdentity(); // Reset
// Enable perspective projection with fovy, aspect, zNear and zFar
gluPerspective(45.0f, aspect, 0.1f, 100.0f);
}
void Engine::Timer(int value)
{
glutPostRedisplay(); // Post re-paint request to activate display()
glutTimerFunc(15, Engine::Timer, 0); // next timer call milliseconds later
}
bool Engine::Run(int argc, char** argv)
{
glutInit(&argc, argv); // Initialize GLUT
glutInitDisplayMode(GLUT_DOUBLE); // Enable double buffered mode
glutInitWindowSize(640, 480); // Set the window's initial width & height
glutInitWindowPosition(50, 50); // Position the window's initial top-left corner
glutCreateWindow("FML"); // Create window with the given title
glutDisplayFunc(Engine::Display); // Register callback handler for window re-paint event
glutReshapeFunc(Engine::Reshape); // Register callback handler for window re-size event
Engine::Init(); // Our own OpenGL initialization
glutTimerFunc(0, Engine::Timer, 0); // Call the next display immediately
glutMainLoop(); // Enter the infinite event-processing loop
return true;
}
void Engine::AddRenderer(renderer_t renderer)
{
Engine::renderers.push_back(renderer);
}
}
using namespace Graphics;
static bool RenderCube()
{
static auto angleCube = 0.0f;
// Render a color-cube consisting of 6 quads with different colors
glLoadIdentity(); // Reset the model-view matrix
glTranslatef(1.5f, 0.0f, -7.0f); // Move right and into the screen
glRotatef(angleCube, 1.0f, 1.0f, 1.0f);
glBegin(GL_QUADS); // Begin drawing the color cube with 6 quads
// Top face (y = 1.0f)
// Define vertices in counter-clockwise (CCW) order with normal pointing out
glColor3f(0.0f, 1.0f, 0.0f); // Green
glVertex3f( 1.0f, 1.0f, -1.0f);
glVertex3f(-1.0f, 1.0f, -1.0f);
glVertex3f(-1.0f, 1.0f, 1.0f);
glVertex3f( 1.0f, 1.0f, 1.0f);
// Bottom face (y = -1.0f)
glColor3f(1.0f, 0.5f, 0.0f); // Orange
glVertex3f( 1.0f, -1.0f, 1.0f);
glVertex3f(-1.0f, -1.0f, 1.0f);
glVertex3f(-1.0f, -1.0f, -1.0f);
glVertex3f( 1.0f, -1.0f, -1.0f);
// Front face (z = 1.0f)
glColor3f(1.0f, 0.0f, 0.0f); // Red
glVertex3f( 1.0f, 1.0f, 1.0f);
glVertex3f(-1.0f, 1.0f, 1.0f);
glVertex3f(-1.0f, -1.0f, 1.0f);
glVertex3f( 1.0f, -1.0f, 1.0f);
// Back face (z = -1.0f)
glColor3f(1.0f, 1.0f, 0.0f); // Yellow
glVertex3f( 1.0f, -1.0f, -1.0f);
glVertex3f(-1.0f, -1.0f, -1.0f);
glVertex3f(-1.0f, 1.0f, -1.0f);
glVertex3f( 1.0f, 1.0f, -1.0f);
// Left face (x = -1.0f)
glColor3f(0.0f, 0.0f, 1.0f); // Blue
glVertex3f(-1.0f, 1.0f, 1.0f);
glVertex3f(-1.0f, 1.0f, -1.0f);
glVertex3f(-1.0f, -1.0f, -1.0f);
glVertex3f(-1.0f, -1.0f, 1.0f);
// Right face (x = 1.0f)
glColor3f(1.0f, 0.0f, 1.0f); // Magenta
glVertex3f(1.0f, 1.0f, -1.0f);
glVertex3f(1.0f, 1.0f, 1.0f);
glVertex3f(1.0f, -1.0f, 1.0f);
glVertex3f(1.0f, -1.0f, -1.0f);
glEnd();
angleCube += 0.2f;
return true;
}
static bool RenderPyramid()
{
static auto anglePyramid = 0.0f;
// Render a pyramid consists of 4 triangles
glLoadIdentity(); // Reset the model-view matrix
glTranslatef(-1.5f, 0.0f, -6.0f); // Move left and into the screen
glRotatef(anglePyramid, 1.0f, 1.0f, 1.0f);
glBegin(GL_TRIANGLES); // Begin drawing the pyramid with 4 triangles
// Front
glColor3f(1.0f, 0.0f, 0.0f); // Red
glVertex3f( 0.0f, 1.0f, 0.0f);
glColor3f(0.0f, 1.0f, 0.0f); // Green
glVertex3f(-1.0f, -1.0f, 1.0f);
glColor3f(0.0f, 0.0f, 1.0f); // Blue
glVertex3f(1.0f, -1.0f, 1.0f);
// Right
glColor3f(1.0f, 0.0f, 0.0f); // Red
glVertex3f(0.0f, 1.0f, 0.0f);
glColor3f(0.0f, 0.0f, 1.0f); // Blue
glVertex3f(1.0f, -1.0f, 1.0f);
glColor3f(0.0f, 1.0f, 0.0f); // Green
glVertex3f(1.0f, -1.0f, -1.0f);
// Back
glColor3f(1.0f, 0.0f, 0.0f); // Red
glVertex3f(0.0f, 1.0f, 0.0f);
glColor3f(0.0f, 1.0f, 0.0f); // Green
glVertex3f(1.0f, -1.0f, -1.0f);
glColor3f(0.0f, 0.0f, 1.0f); // Blue
glVertex3f(-1.0f, -1.0f, -1.0f);
// Left
glColor3f(1.0f,0.0f,0.0f); // Red
glVertex3f( 0.0f, 1.0f, 0.0f);
glColor3f(0.0f,0.0f,1.0f); // Blue
glVertex3f(-1.0f,-1.0f,-1.0f);
glColor3f(0.0f,1.0f,0.0f); // Green
glVertex3f(-1.0f,-1.0f, 1.0f);
glEnd(); // Done drawing the pyramid
anglePyramid += 0.25f;
return true;
}
int main(int argc, char** argv)
{
Engine::AddRenderer(RenderCube);
Engine::AddRenderer(RenderPyramid);
return Engine::Run(argc, argv);
}
Images of the resulting shapes rotating
As you can see the shapes are acting weird - you can see the back of them even though I used the glDepthFunc.
The OS/driver is under no obligation to give you any depth buffer bits unless you specifically request them; zero bits, no depth buffering.
As #BDL pointed out, for GLUT that means ORing in GLUT_DEPTH to your glutInitDisplayMode() parameter.
I need to draw a cube to indicate coordinate in OpenGL 3.3 core profile.It works fine without glutInitContextVersion (3, 3); but it becomes totally black when glutInitContextVersion (3, 3); applied.
Here is the drawing code.
void display() {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Clear color and depth buffers
glMatrixMode(GL_MODELVIEW); // To operate on model-view matrix
// Render a color-cube consisting of 6 quads with different colors
glLoadIdentity(); // Reset the model-view matrix
glTranslatef(1.5f, 0.0f, -7.0f); // Move right and into the screen
glBegin(GL_QUADS); // Begin drawing the color cube with 6 quads
// Top face (y = 1.0f)
// Define vertices in counter-clockwise (CCW) order with normal pointing out
glColor3f(0.0f, 1.0f, 0.0f); // Green
glVertex3f( 1.0f, 1.0f, -1.0f);
glVertex3f(-1.0f, 1.0f, -1.0f);
glVertex3f(-1.0f, 1.0f, 1.0f);
glVertex3f( 1.0f, 1.0f, 1.0f);
// Bottom face (y = -1.0f)
glColor3f(1.0f, 0.5f, 0.0f); // Orange
glVertex3f( 1.0f, -1.0f, 1.0f);
glVertex3f(-1.0f, -1.0f, 1.0f);
glVertex3f(-1.0f, -1.0f, -1.0f);
glVertex3f( 1.0f, -1.0f, -1.0f);
// Front face (z = 1.0f)
glColor3f(1.0f, 0.0f, 0.0f); // Red
glVertex3f( 1.0f, 1.0f, 1.0f);
glVertex3f(-1.0f, 1.0f, 1.0f);
glVertex3f(-1.0f, -1.0f, 1.0f);
glVertex3f( 1.0f, -1.0f, 1.0f);
// Back face (z = -1.0f)
glColor3f(1.0f, 1.0f, 0.0f); // Yellow
glVertex3f( 1.0f, -1.0f, -1.0f);
glVertex3f(-1.0f, -1.0f, -1.0f);
glVertex3f(-1.0f, 1.0f, -1.0f);
glVertex3f( 1.0f, 1.0f, -1.0f);
// Left face (x = -1.0f)
glColor3f(0.0f, 0.0f, 1.0f); // Blue
glVertex3f(-1.0f, 1.0f, 1.0f);
glVertex3f(-1.0f, 1.0f, -1.0f);
glVertex3f(-1.0f, -1.0f, -1.0f);
glVertex3f(-1.0f, -1.0f, 1.0f);
// Right face (x = 1.0f)
glColor3f(1.0f, 0.0f, 1.0f); // Magenta
glVertex3f(1.0f, 1.0f, -1.0f);
glVertex3f(1.0f, 1.0f, 1.0f);
glVertex3f(1.0f, -1.0f, 1.0f);
glVertex3f(1.0f, -1.0f, -1.0f);
glEnd(); // End of drawing color-cube
glutSwapBuffers(); // Swap the front and back frame buffers (double buffering)
}
Here is the code in main function:
int main(int argc, char** argv) {
glutInit(&argc, argv); // Initialize GLUT
glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA); // Enable double buffered mode
glutInitContextVersion (3, 3);
glutInitWindowSize(640, 480); // Set the window's initial width & height
glutInitWindowPosition(50, 50); // Position the window's initial top-left corner
glutCreateWindow(title); // Create window with the given title
glutDisplayFunc(display); // Register callback handler for window re-paint event
glutReshapeFunc(reshape); // Register callback handler for window re-size event
initGL(); // Our own OpenGL initialization
glutMainLoop(); // Enter the infinite event-processing loop
return 0;
}
How to draw a cube in OpenGL 3.3 core profile?
glBegin and friends are deprecated and removed from the newer versions (3.2 onward).
Instead you need to upload the vertex data to Vertex Buffer Objects. Then use glVertexAttribPointer to tell openGL how the data is laid out.
Besides that you need to write shaders.
Fixed function pipeline (glVertex, glBegin etc.) does not exist in Core Profile.
I make OpenGL application that draw cube.
I want to add anti aliasing but have no success.
Maybe someone can help (User Xcode 6.1.1, GLUT, OpenGL) ?
I need create antialiasing without ay external libraries.
Result of code below.
GLfloat xRotated, yRotated, zRotated; void init(void){
glClearColor(0,0,0,0);
glEnable (GL_DEPTH_TEST);
// Turn on antialiasing, and give hint to do the best
// job possible.
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_BLEND);
glEnable(GL_POINT_SMOOTH);
glHint(GL_POINT_SMOOTH_HINT, GL_LINEAR);
glEnable(GL_LINE_SMOOTH);
glHint(GL_LINE_SMOOTH_HINT, GL_LINEAR);
glEnable(GL_POLYGON_SMOOTH);
glHint(GL_POLYGON_SMOOTH_HINT, GL_LINEAR);
glEnable(GL_MULTISAMPLE); } void DrawCube(void) {
glMatrixMode(GL_MODELVIEW);
// clear the drawing buffer.
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
glTranslatef(0.0,0.0,-10.5);
glRotatef(xRotated,1.0,0.0,0.0);
// rotation about Y axis
glRotatef(yRotated,0.0,1.0,0.0);
// rotation about Z axis
glRotatef(zRotated,0.0,0.0,1.0);
glBegin(GL_QUADS); // Draw The Cube Using quads
glColor3f(0.0f,1.0f,0.0f); // Color Blue
glVertex3f( 1.0f, 1.0f,-1.0f); // Top Right Of The Quad (Top)
glVertex3f(-1.0f, 1.0f,-1.0f); // Top Left Of The Quad (Top)
glVertex3f(-1.0f, 1.0f, 1.0f); // Bottom Left Of The Quad (Top)
glVertex3f( 1.0f, 1.0f, 1.0f); // Bottom Right Of The Quad (Top)
glColor3f(1.0f,0.5f,0.0f); // Color Orange
glVertex3f( 1.0f,-1.0f, 1.0f); // Top Right Of The Quad (Bottom)
glVertex3f(-1.0f,-1.0f, 1.0f); // Top Left Of The Quad (Bottom)
glVertex3f(-1.0f,-1.0f,-1.0f); // Bottom Left Of The Quad (Bottom)
glVertex3f( 1.0f,-1.0f,-1.0f); // Bottom Right Of The Quad (Bottom)
glColor3f(1.0f,0.0f,0.0f); // Color Red
glVertex3f( 1.0f, 1.0f, 1.0f); // Top Right Of The Quad (Front)
glVertex3f(-1.0f, 1.0f, 1.0f); // Top Left Of The Quad (Front)
glVertex3f(-1.0f,-1.0f, 1.0f); // Bottom Left Of The Quad (Front)
glVertex3f( 1.0f,-1.0f, 1.0f); // Bottom Right Of The Quad (Front)
glColor3f(1.0f,1.0f,0.0f); // Color Yellow
glVertex3f( 1.0f,-1.0f,-1.0f); // Top Right Of The Quad (Back)
glVertex3f(-1.0f,-1.0f,-1.0f); // Top Left Of The Quad (Back)
glVertex3f(-1.0f, 1.0f,-1.0f); // Bottom Left Of The Quad (Back)
glVertex3f( 1.0f, 1.0f,-1.0f); // Bottom Right Of The Quad (Back)
glColor3f(0.0f,0.0f,1.0f); // Color Blue
glVertex3f(-1.0f, 1.0f, 1.0f); // Top Right Of The Quad (Left)
glVertex3f(-1.0f, 1.0f,-1.0f); // Top Left Of The Quad (Left)
glVertex3f(-1.0f,-1.0f,-1.0f); // Bottom Left Of The Quad (Left)
glVertex3f(-1.0f,-1.0f, 1.0f); // Bottom Right Of The Quad (Left)
glColor3f(1.0f,0.0f,1.0f); // Color Violet
glVertex3f( 1.0f, 1.0f,-1.0f); // Top Right Of The Quad (Right)
glVertex3f( 1.0f, 1.0f, 1.0f); // Top Left Of The Quad (Right)
glVertex3f( 1.0f,-1.0f, 1.0f); // Bottom Left Of The Quad (Right)
glVertex3f( 1.0f,-1.0f,-1.0f); // Bottom Right Of The Quad (Right)
glEnd(); // End Drawing The Cube
glFlush(); } void animation(void) {
yRotated += 0.1;
xRotated += 0.2;
DrawCube(); } void reshape(int x, int y) {
if (y == 0 || x == 0) return; //Nothing is visible then, so return
//Set a new projection matrix
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(40.0,(GLdouble)x/(GLdouble)y,0.5,20.0);
glMatrixMode(GL_MODELVIEW);
glViewport(0,0,x,y); //Use the whole window for rendering } int main(int argc, char** argv){
glutInit(&argc, argv);
//we initizlilze the glut. functions
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGBA | GLUT_DEPTH | GLUT_MULTISAMPLE);
glutInitWindowPosition(100, 100);
glutCreateWindow(argv[0]);
init();
glutDisplayFunc(DrawCube);
glutReshapeFunc(reshape);
//Set the function for the animation.
glutIdleFunc(animation);
glutMainLoop();
return 0; }
GLUT lacks the setting of the number of samples. Freeglut does. To enable it, use
glutSetOption(GLUT_MULTISAMPLE, 8);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH | GLUT_MULTISAMPLE);
And remember to glEnable it
void enableMultisample(int msaa)
{
if (msaa)
{
glEnable(GL_MULTISAMPLE);
glHint(GL_MULTISAMPLE_FILTER_HINT_NV, GL_NICEST);
// detect current settings
GLint iMultiSample = 0;
GLint iNumSamples = 0;
glGetIntegerv(GL_SAMPLE_BUFFERS, &iMultiSample);
glGetIntegerv(GL_SAMPLES, &iNumSamples);
printf("MSAA on, GL_SAMPLE_BUFFERS = %d, GL_SAMPLES = %d\n", iMultiSample, iNumSamples);
}
else
{
glDisable(GL_MULTISAMPLE);
printf("MSAA off\n");
}
}
I'm currently learning OpenGL and have been using it with SDL2 and when trying to run a simple program I am getting a black screen. Any help would be appreciated. I'm using OpenGL 2.1 and vc compiler.
Here's my code
#include <iostream>
#include <SDL.h>
#include <Windows.h>
#include <gl/GL.h>
#include <gl/GLU.h>
using namespace std;
int main(int argc, char* argv[]) {
int width, height;
width = 640;
height = 480;
SDL_Init(SDL_INIT_EVERYTHING);
SDL_Window* win;
win = SDL_CreateWindow("SDL Application", 100, 100, width, height, SDL_WINDOW_SHOWN | SDL_WINDOW_OPENGL);
SDL_GLContext context;
context = SDL_GL_CreateContext(win);
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24);
height = (height <= 0) ? height = height : height = 1;
glViewport(0, 0, width, height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45.0f, (GLfloat) width / (GLfloat) height, 0.1f, 100.0f);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glShadeModel(GL_SMOOTH);
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glClearDepth(1.0f);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
SDL_GL_SwapWindow(win);
glColor3f(1.0f, 1.0f, 1.0f);
glTranslatef(-1.5f, 0.0f, -6.0f);
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();
glTranslatef(3.0f, 0.0f, 0.0f);
glBegin(GL_QUADS);
glVertex3f(-1.0f, 1.0f, 0.0f);
glVertex3f(1.0f, 1.0f, 0.0f);
glVertex3f(1.0f, -1.0f, 0.0f);
glVertex3f(-1.0f, -1.0f, 0.0f);
glEnd();
SDL_Delay(5000);
SDL_GL_DeleteContext(context);
SDL_DestroyWindow(win);
SDL_Quit();
return 0;
}
The order of those is wrong:
SDL_GLContext context;
context = SDL_GL_CreateContext(win);
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24);
The OpenGL context attributes must be set before creating the context (they are state variables, that control the context creation process).
This makes no sense: First you clear, then you swap, then you draw (into a then undefined back buffer, since the content of the back buffer is undefined after a swap) and then you don't swap.
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
SDL_GL_SwapWindow(win);
glColor3f(1.0f, 1.0f, 1.0f);
/* this translate will move the triangle out
* of the NDC space i.e. it gets clipped or
* won't be visible at all. */
glTranslatef(-1.5f, 0.0f, -6.0f);
glBegin(GL_TRIANGLES);
glVertex3f(0.0f, 1.0f, 0.0f);
This should be something like
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glColor3f(1.0f, 1.0f, 1.0f);
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();
glTranslatef(3.0f, 0.0f, 0.0f);
glBegin(GL_QUADS);
glVertex3f(-1.0f, 1.0f, 0.0f);
glVertex3f(1.0f, 1.0f, 0.0f);
glVertex3f(1.0f, -1.0f, 0.0f);
glVertex3f(-1.0f, -1.0f, 0.0f);
glEnd();
SDL_GL_SwapWindow(win);
SDL_Delay(5000);
To make any sense at all. There are still loads of problems with the rest of the code, but if you change it that way, you should at least see some white triangle on a black ground.
Recently I have been looking into OpenGL, and I've got up to the stage were I want to texture things. I thought I would start with texturing a simple cube.
I currently have this code, and understand fully how it works:
#include <glut.h>
#define WINDOW_WIDTH 400
#define WINDOW_HEIGHT 400
float angle = 30.0f;
void Draw() {
glLoadIdentity(); //Reset the drawing perspective
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); //Clears the buffers
//Add positioned light
GLfloat lightColor0[] = {0.5f, 0.5f, 0.5f, 1.0f}; //Color intensity
GLfloat lightPos0[] = {0.0f, 0.0f, 0.0f, 1.0f}; //Positioned at..
glLightfv(GL_LIGHT0, GL_DIFFUSE, lightColor0); //Set our light colour
glLightfv(GL_LIGHT0, GL_POSITION, lightPos0); //Set our light position
glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 200);
glRotatef(angle,1.0f,1.0f,1.0f); //Rotate around the origin
glScalef(0.4f, 0.4f, 0.4f); //Scale the shape down
glBegin(GL_QUADS); //Start drawing a Quad
glColor3f(1.0f,0.0f,0.0f); //Set the colour to Red
glVertex3f( 1.0f, 1.0f,-1.0f); //Top right of the quad (Top Face)
glVertex3f(-1.0f, 1.0f,-1.0f); //Top left of the quad (Top Face)
glVertex3f(-1.0f, 1.0f, 1.0f); //Bottom left of the quad (Top Face)
glVertex3f( 1.0f, 1.0f, 1.0f); //Bottom right of the quad (Top Face)
glVertex3f( 1.0f,-1.0f, 1.0f); //Top right of the quad (Bottom Face)
glVertex3f(-1.0f,-1.0f, 1.0f); //Top left of the quad (Bottom Face)
glVertex3f(-1.0f,-1.0f,-1.0f); //Bottom left of the quad (Bottom Face)
glVertex3f( 1.0f,-1.0f,-1.0f); //Bottom right of the quad (Bottom Face)
glVertex3f( 1.0f, 1.0f, 1.0f); //Top right of the quad (Front Face)
glVertex3f(-1.0f, 1.0f, 1.0f); //Top left of the quad (Front Face)
glVertex3f(-1.0f,-1.0f, 1.0f); //Bottom left of the quad (Front Face)
glVertex3f( 1.0f,-1.0f, 1.0f); //Bottom right of the quad (Front Face)
glVertex3f( 1.0f,-1.0f,-1.0f); //Top right of the quad (Back Face)
glVertex3f(-1.0f,-1.0f,-1.0f); //Top left of the quad (Back Face)
glVertex3f(-1.0f, 1.0f,-1.0f); //Bottom left of the quad (Back Face)
glVertex3f( 1.0f, 1.0f,-1.0f); //Bottom right of the quad (Back Face)
glVertex3f(-1.0f, 1.0f, 1.0f); //Top right of the quad (Left Face)
glVertex3f(-1.0f, 1.0f,-1.0f); //Top left of the quad (Left Face)
glVertex3f(-1.0f,-1.0f,-1.0f); //Bottom left of the quad (Left Face)
glVertex3f(-1.0f,-1.0f, 1.0f); //Bottom right of the quad (Left Face)
glVertex3f( 1.0f, 1.0f,-1.0f); //Top right of the quad (Right Face)
glVertex3f( 1.0f, 1.0f, 1.0f); //Top left of the quad (Right Face)
glVertex3f( 1.0f,-1.0f, 1.0f); //Bottom left of the quad (Right Face)
glVertex3f( 1.0f,-1.0f,-1.0f); //Bottom right of the quad (Right Face)
glEnd(); //Finished Drawing The Quad
glutSwapBuffers(); //Send the 3D scene to the screen
}
void Update(int value){ //Our update function
angle+=0.5f; //Increase the angle by 5
if(angle>360){ //If the angle is greater than 360
angle=0; //Set the angle to 0
}
glutPostRedisplay(); //Tell it that the scene has changed
glutTimerFunc(25,Update,0); //Call "Update" again in another 25ms
}
void Initialize() {
glEnable(GL_DEPTH_TEST);
glEnable(GL_COLOR_MATERIAL);
glEnable(GL_LIGHTING); //Enable lighting
glEnable(GL_LIGHT0); //Enable light No. 0
glEnable(GL_NORMALIZE); //Automatically "normalize" normals
glShadeModel(GL_SMOOTH); //Enable smooth shading (nice effect)
glClearColor(0.0, 0.0, 0.0, 0.0); //Background RGBA
glMatrixMode(GL_MODELVIEW); //MODELVIEW view
glLoadIdentity(); //Start at origin
glOrtho(0.0, 1.0, 0.0, 1.0, -1.0, 1.0); //Set the scale
//X axis = 0 to 1. Y = 0 to 1. Z = -1 to 1.
}
int main() {
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH); //The display mode
glutInitWindowSize(WINDOW_WIDTH, WINDOW_HEIGHT); //Window Size
glutInitWindowPosition(200, 200); //Window Position
glutCreateWindow("Lighting!"); //Creates a window with the name "Lighting!"
Initialize(); //Call our initialize function.
glutDisplayFunc(Draw); //"Draw" then refresh the window
glutTimerFunc(25,Update,0); //Call "Update" 25ms after program starts
glutMainLoop(); //Process events etc. Also keeps the window open.
return 0; //End the program
}
However after reading many, MANY texturing tutorials (I mean literally all of the ones I could find on the web); I'm still confused about how I would add it to this program.
I know that I have to load the texture (somehow) and then bind it using the glBindTexture function before I draw the cube, but I think there is something else I need to do in-between (and I don't know how to load the image properly either).
For loading texture files (png, jpg...) use this:
(don't forget to install SDL and SDL_image libraries)
#include <SDL/SDL.h>
#include <SDL/SDL_image.h>
GLuint texture_alloc(const char *tex_name, int alpha)
{
GLuint tex_num;
SDL_Surface *tex_img;
glGenTextures(1, &tex_num);
if(tex_img = (SDL_Surface *) IMG_Load(tex_name)) {
glBindTexture(GL_TEXTURE_2D, tex_num);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_TRUE);
if (alpha==1)
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tex_img->w, tex_img->h, 0, GL_RGBA, GL_UNSIGNED_BYTE, tex_img->pixels);
else
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, tex_img->w, tex_img->h, 0, GL_RGB, GL_UNSIGNED_BYTE, tex_img->pixels);
SDL_FreeSurface (tex_img);
}
return tex_num;
}
For setting texture coordinates use glTexCoord function:
glTexCoord2f(0.0f, 0.0f);
glVertex3f( 1.0f, 1.0f,-1.0f);
glTexCoord2f(1.0f, 0.0f);
glVertex3f(-1.0f, 1.0f,-1.0f);
.
.
.
I recommend looking at SOIL, an OpenGL image loading library - its what I use.
As far as getting a texture working, its pretty much:
Unsigned int texture = SOIL_load_OGL_texture(imagePath.c_str(), SOIL_CREATE_NEW_ID, SOIL_LOAD_AUTO, SOIL_FLAG_MIPMAPS);
glBindTexture(texture);
You do however have to use texture co-ordinates so that opengl knows how to wrap your texture. Heres some sample calls that render cube.
int size = 1;
// Begin Rending
glBegin(GL_QUADS);
{
// Face 1
glNormal3f( 0.0f, 0.0f, 1.0f);
glTexCoord2f(0.0f, 0.0f);
glVertex3f( m_size, m_size,-m_size);
glTexCoord2f(1.0f, 0.0f);
glVertex3f(-m_size, m_size,-m_size);
glTexCoord2f(1.0f, 1.0f);
glVertex3f(-m_size, m_size, m_size);
glTexCoord2f(0.0f, 1.0f);
glVertex3f( m_size, m_size, m_size);
// Face 2
glNormal3f( 0.0f, 0.0f,-1.0f);
glTexCoord2f(0.0f, 0.0f);
glVertex3f( m_size,-m_size, m_size);
glTexCoord2f(1.0f, 0.0f);
glVertex3f(-m_size,-m_size, m_size);
glTexCoord2f(1.0f, 1.0f);
glVertex3f(-m_size,-m_size,-m_size);
glTexCoord2f(0.0f, 1.0f);
glVertex3f( m_size,-m_size,-m_size);
// Face 3
glTexCoord2f(0.0f, 0.0f);
glVertex3f( m_size, m_size, m_size);
glTexCoord2f(1.0f, 0.0f);
glVertex3f(-m_size, m_size, m_size);
glTexCoord2f(1.0f, 1.0f);
glVertex3f(-m_size,-m_size, m_size);
glTexCoord2f(0.0f, 1.0f);
glVertex3f( m_size,-m_size, m_size);
// Face 4
glNormal3f( 0.0f,-1.0f, 0.0f);
glTexCoord2f(0.0f, 0.0f);
glVertex3f( m_size,-m_size,-m_size);
glTexCoord2f(1.0f, 0.0f);
glVertex3f(-m_size,-m_size,-m_size);
glTexCoord2f(1.0f, 1.0f);
glVertex3f(-m_size, m_size,-m_size);
glTexCoord2f(0.0f, 1.0f);
glVertex3f( m_size, m_size,-m_size);
// Face 5
glNormal3f( 1.0f, 0.0f, 0.0f);
glTexCoord2f(0.0f, 0.0f);
glVertex3f(-m_size, m_size, m_size);
glTexCoord2f(1.0f, 0.0f);
glVertex3f(-m_size, m_size,-m_size);
glTexCoord2f(1.0f, 1.0f);
glVertex3f(-m_size,-m_size,-m_size);
glTexCoord2f(0.0f, 1.0f);
glVertex3f(-m_size,-m_size, m_size);
// Face 6
glNormal3f( 1.0f, 0.0f, 0.0f);
glTexCoord2f(0.0f, 0.0f);
glVertex3f( m_size, m_size,-m_size);
glTexCoord2f(1.0f, 0.0f);
glVertex3f( m_size, m_size, m_size);
glTexCoord2f(1.0f, 1.0f);
glVertex3f( m_size,-m_size, m_size);
glTexCoord2f(0.0f, 1.0f);
glVertex3f( m_size,-m_size,-m_size);
}
glEnd();
I think the part your missing is the concept of texture coordinates.
Textures are 2d right? So, when you're pushing the 3d points of your object to the graphics card, if you want it textured you also need to associate that 3d point with a position in a texture image which you do with a pair of texture coordinates (pair because textures are 2d)... Take a look at glTexCoord2f()... If you make a call to that right before a call to glVertex3f() you'll associate that 3d point with a point in the image... If you do that for all the points that make up a primitive opengl can interpolate for all the points in between...
For image loading you can also use the SDL-image Library:
http://www.libsdl.org/projects/SDL_image/
It is very handy.
You can use the glaux code from the http://nehe.gamedeve.net/ this also is pretty simple.
AUX_RGBImageRec* LoadBMP(char* Filename)
{
FILE *File = NULL;
if ( !Filename )
return NULL;
File = fopen(Filename,"r");
if ( !Filename )
return NULL;
fclose(File);
return auxDIBImageLoad(Filename);
}
int LoadTextures()
{
int Status = FALSE;
AUX_RGBImageRec *TextureImage[1];
memset(TextureImage,0,sizeof(void*)*1);
if ( TextureImage[0] = LoadBMP("GoneFishing.bmp") )
{
Status = true;
if(texture[0] == -1)
glGenTextures(1,&texture[0]);
glBindTexture(GL_TEXTURE_2D,texture[0]);
// Generate The Texture
glTexImage2D(GL_TEXTURE_2D, 0, 3, TextureImage[0]->sizeX, TextureImage[0]->sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE, TextureImage[0]->data);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR); // Linear Filtering
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); // Linear Filtering
}
if (TextureImage[0]) // If Texture Exists
{
if (TextureImage[0]->data) // If Texture Image Exists
{
free(TextureImage[0]->data); // Free The Texture Image Memory
}
free(TextureImage[0]); // Free The Image Structure
}
return Status;
}