I am writing a program that draws a rectangle with the mouse when and only when the user selects it in the menu, if the user does not select it will not draw. Up to now, I have successfully drawn the rectangle with the mouse, now how can I create a menu so that the user can choose to draw the rectangle? This is my program:
struct Position
{
Position() : x(0), y(0) {}
float x, y;
};
Position start, finish;
void mouse(int button, int state, int x, int y)
{
if (button == GLUT_LEFT_BUTTON && state == GLUT_DOWN)
{
start.x = finish.x = x;
start.y = finish.y = y;
}
if (button == GLUT_LEFT_BUTTON && state == GLUT_UP)
{
finish.x = x;
finish.y = y;
}
glutPostRedisplay();
}
void motion(int x, int y)
{
finish.x = x;
finish.y = y;
glutPostRedisplay();
}
void display()
{
glClear(GL_COLOR_BUFFER_BIT);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
double w = glutGet(GLUT_WINDOW_WIDTH);
double h = glutGet(GLUT_WINDOW_HEIGHT);
glOrtho(0, w, h, 0, -1, 1);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glPushMatrix();
glBegin(GL_LINE_LOOP);
glVertex2f(start.x, start.y);
glVertex2f(finish.x, start.y);
glVertex2f(finish.x, finish.y);
glVertex2f(start.x, finish.y);
glEnd();
glPopMatrix();
glutSwapBuffers();
}
void menu(int choice)
{
switch (choice)
{
case 1:
// What to write in here?
break;
}
glutPostRedisplay();
}
int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
glutInitWindowSize(640, 480);
glutInitWindowPosition(100, 100);
glutCreateWindow("");
glutCreateMenu(menu);
glutAddMenuEntry("Rectangle", 1);
glutAttachMenu(GLUT_RIGHT_BUTTON);
glutMouseFunc(mouse);
glutMotionFunc(motion);
glutDisplayFunc(display);
glutMainLoop();
}
Add a variable that indicates which shape has to be drawn:
int shape = 0;
Set the variable in menu:
void menu(int choice)
{
switch (choice)
{
case 1:
shape = 1
break;
}
glutPostRedisplay();
}
Draw the scene dependent on shape:
void display()
{
glClear(GL_COLOR_BUFFER_BIT);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
double w = glutGet(GLUT_WINDOW_WIDTH);
double h = glutGet(GLUT_WINDOW_HEIGHT);
glOrtho(0, w, h, 0, -1, 1);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
if (shape == 1)
{
glPushMatrix();
glBegin(GL_LINE_LOOP);
glVertex2f(start.x, start.y);
glVertex2f(finish.x, start.y);
glVertex2f(finish.x, finish.y);
glVertex2f(start.x, finish.y);
glEnd();
glPopMatrix();
}
glutSwapBuffers();
}
Ive been working in glfw c++ and want to get input from the mouse wheel by using the glfwSetScrollCallback() and I put it in a window class that I created because it requires a glfw window. I created a scroll_callback function that adjusts the fov for the camera that I initialize in a camera class. The glfwSetScrollCallback() uses that static void of my scroll_callback function in my camera class. However, I cant seem how to initialize a the fov variable in my camera.h and use it in the static void in my camera.cpp. I tried changing it to a static public variable because I need to call it in my main class but it didnt work. Any thoughts thank you!!!
camera.h
#pragma once
#include <GL\glew.h>
#include <glm\glm.hpp>
#include <glm\gtc\matrix_transform.hpp>
#include <GLFW\glfw3.h>
class Camera
{
public:
Camera();
Camera(glm::vec3 startPosition, glm::vec3 startUp, GLfloat startYaw, GLfloat startPitch, GLfloat startMoveSpeed, GLfloat startTurnSpeed);
void keyControl(bool* keys, GLfloat deltaTime);
void mouseControl(GLfloat xChange, GLfloat yChange);
static float fov;
glm::mat4 calculateViewMatrix();
~Camera();
static void scroll_callback(GLFWwindow* window, double xoffset, double yoffset);
private:
glm::vec3 position;
glm::vec3 front;
glm::vec3 up;
glm::vec3 right;
glm::vec3 worldUp;
GLfloat yaw;
GLfloat pitch;
GLfloat moveSpeed;
GLfloat turnSpeed;
void update();
};
Camera.cpp
#include "Camera.h"
#include <iostream>
Camera::Camera() {}
Camera::Camera(glm::vec3 startPosition, glm::vec3 startUp, GLfloat startYaw, GLfloat startPitch, GLfloat startMoveSpeed, GLfloat startTurnSpeed)
{
position = startPosition;
worldUp = startUp;
yaw = startYaw;
pitch = startPitch;
front = glm::vec3(0.0f, 0.0f, -1.0f);
moveSpeed = startMoveSpeed;
turnSpeed = startTurnSpeed;
update();
}
void Camera::keyControl(bool* keys, GLfloat deltaTime)
{
GLfloat velocity = moveSpeed * deltaTime;
if (keys[GLFW_KEY_W] || keys[GLFW_KEY_UP])
{
position += front * velocity;
}
if (keys[GLFW_KEY_S] || keys[GLFW_KEY_DOWN])
{
position -= front * velocity;
}
if (keys[GLFW_KEY_A] || keys[GLFW_KEY_LEFT])
{
position -= right * velocity;
}
if (keys[GLFW_KEY_D] || keys[GLFW_KEY_RIGHT])
{
position += right * velocity;
}
}
void Camera::mouseControl(GLfloat xChange, GLfloat yChange)
{
xChange *= turnSpeed;
yChange *= turnSpeed;
yaw += xChange;
pitch += yChange;
if (pitch > 89.0f)
{
pitch = 89.0f;
}
if (pitch < -89.0f)
{
pitch = -89.0f;
}
update();
}
void Camera::scroll_callback(GLFWwindow* window, double xoffset, double yoffset)
{
if (fov > 1.0f && fov < 45.0f)
fov -= yoffset;
else if (fov <= 1.0f)
fov = 1.0f;
else if (fov >= 45.0f)
fov = 45.0f;
}
glm::mat4 Camera::calculateViewMatrix()
{
return glm::lookAt(position, position + front, up);
}
void Camera::update()
{
front.x = cos(glm::radians(yaw)) * cos(glm::radians(pitch));
front.y = sin(glm::radians(pitch));
front.z = sin(glm::radians(yaw)) * cos(glm::radians(pitch));
front = glm::normalize(front);
right = glm::normalize(glm::cross(front, worldUp));
up = glm::normalize(glm::cross(right, front));
}
Camera::~Camera()
{
}
window.cpp
#include "Window.h"
#include "Camera.h"
#include <iostream>
Window::Window()
{
width = 800;
height = 800;
for (size_t i = 0; i < 1024; i++)
{
keys[i] = 0;
}
}
Window::Window(GLint windowWidth, GLint windowHeight)
{
width = windowWidth;
height = windowHeight;
for (size_t i = 0; i < 1024; i++)
{
keys[i] = 0;
}
}
int Window::Initialise()
{
if (!glfwInit())
{
printf("Error Initialising GLFW");
glfwTerminate();
return 1;
}
// Setup GLFW Windows Properties
// OpenGL version
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
// Core Profile
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
// Allow forward compatiblity
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
// Create the window
mainWindow = glfwCreateWindow(width, height, "Test Window", NULL, NULL);
if (!mainWindow)
{
printf("Error creating GLFW window!");
glfwTerminate();
return 1;
}
// Get buffer size information
glfwGetFramebufferSize(mainWindow, &bufferWidth, &bufferHeight);
// Set the current context
glfwMakeContextCurrent(mainWindow);
// Handle Key + Mouse Input
createCallbacks();
glfwSetScrollCallback(mainWindow, Camera::scroll_callback);
glfwSetInputMode(mainWindow, GLFW_CURSOR, GLFW_CURSOR_DISABLED);
// Allow modern extension access
glewExperimental = GL_TRUE;
GLenum error = glewInit();
if (error != GLEW_OK)
{
printf("Error: %s", glewGetErrorString(error));
glfwDestroyWindow(mainWindow);
glfwTerminate();
return 1;
}
glEnable(GL_DEPTH_TEST);
// Create Viewport
glViewport(0, 0, bufferWidth, bufferHeight);
glfwSetWindowUserPointer(mainWindow, this);
}
void Window::createCallbacks()
{
glfwSetKeyCallback(mainWindow, handleKeys);
glfwSetCursorPosCallback(mainWindow, handleMouse);
}
GLfloat Window::getXChange()
{
GLfloat theChange = xChange;
xChange = 0.0f;
return theChange;
}
GLfloat Window::getYChange()
{
GLfloat theChange = yChange;
yChange = 0.0f;
return theChange;
}
void Window::handleKeys(GLFWwindow* window, int key, int code, int action, int mode)
{
Window* theWindow = static_cast<Window*>(glfwGetWindowUserPointer(window));
if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS)
{
glfwSetWindowShouldClose(window, GL_TRUE);
}
if (key >= 0 && key < 1024)
{
if (action == GLFW_PRESS)
{
theWindow->keys[key] = true;
}
else if (action == GLFW_RELEASE)
{
theWindow->keys[key] = false;
}
}
}
void Window::handleMouse(GLFWwindow* window, double xPos, double yPos)
{
Window* theWindow = static_cast<Window*>(glfwGetWindowUserPointer(window));
if (theWindow->mouseFirstMoved)
{
theWindow->lastX = xPos;
theWindow->lastY = yPos;
theWindow->mouseFirstMoved = false;
}
theWindow->xChange = xPos - theWindow->lastX;
theWindow->yChange = theWindow->lastY - yPos;
theWindow->lastX = xPos;
theWindow->lastY = yPos;
}
Window::~Window()
{
glfwDestroyWindow(mainWindow);
glfwTerminate();
}
Im having a problem with glutKeyboardUpFunc. Everytime I press a key and don't release it, the callback of glutKeyboardUpFunc stills gets called, the longer I hold the key the more times the callback executes.
Here is a quick example I put up:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <math.h>
#include <float.h>
#include <time.h>
#include <GL/glut.h>
#define DEBUG 1
/* VARI�VEIS GLOBAIS */
typedef struct {
GLboolean doubleBuffer;
GLint delay;
} Estado;
typedef struct {
GLfloat x;
GLfloat y;
GLfloat height;
GLfloat width;
GLfloat y_accelaration;
} Plataforma;
//save stage coordinates
typedef struct {
GLfloat top;
GLfloat bottom;
GLfloat right;
GLfloat left;
} Screen;
Estado estado;
Screen ecra;
Plataforma plataforma;
GLfloat tab_speed = 2.0 / 20.0;
GLfloat y_accelaration = 0.001;
void Init(void) {
struct tm *current_time;
time_t timer = time(0);
estado.delay = 42;
estado.doubleBuffer = GL_TRUE;
plataforma.height = 0.3;
plataforma.width = 0.05;
plataforma.y_accelaration = 0;
plataforma.y = 0;
// L� hora do Sistema
current_time = localtime(&timer);
glClearColor(0.3, 0.3, 0.3, 0.0);
glEnable(GL_POINT_SMOOTH);
glEnable(GL_LINE_SMOOTH);
glEnable(GL_POLYGON_SMOOTH);
}
void Reshape(int width, int height) {
GLint size;
GLfloat ratio = (GLfloat) width / height;
GLfloat ratio1 = (GLfloat) height / width;
if (width < height)
size = width;
else
size = height;
glViewport(0, 0, width, height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
if (width < height) {
ecra.left = -1;
ecra.right = 1;
ecra.bottom = -1 * ratio1;
ecra.top = 1 * ratio1;
gluOrtho2D(-1, 1, -1 * ratio1, 1 * ratio1);
} else {
ecra.left = -1 * ratio;
ecra.right = 1 * ratio;
ecra.bottom = -1;
ecra.top = 1;
gluOrtho2D(-1 * ratio, 1 * ratio, -1, 1);
}
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
void desenhar_plataforma(Plataforma pf) {
glColor3f(1.0f, 0.0f, 0.0f);
glBegin(GL_POLYGON);
glVertex2f(pf.x - pf.width / 2, pf.y - pf.height / 2);
glVertex2f(pf.x + pf.width / 2, pf.y - pf.height / 2);
glVertex2f(pf.x + pf.width / 2, pf.y + pf.height / 2);
glVertex2f(pf.x - pf.width / 2, pf.y + pf.height / 2);
glEnd();
}
void Draw(void) {
glClear(GL_COLOR_BUFFER_BIT);
plataforma.x = ecra.left + 0.1;
desenhar_plataforma(plataforma);
glFlush();
if (estado.doubleBuffer)
glutSwapBuffers();
}
void Key(unsigned char key, int x, int y) {
switch (key) {
case 'a':
plataforma.y += tab_speed;
glutPostRedisplay();
break;
case 's':
plataforma.y -= tab_speed;
glutPostRedisplay();
break;
}
}
void KeyUp(unsigned char key, int x, int y) {
if (DEBUG)
printf("Key Up %c\n", key);
}
int main(int argc, char **argv) {
estado.doubleBuffer = GL_TRUE;
glutInit(&argc, argv);
glutInitWindowPosition(0, 0);
glutInitWindowSize(800, 600);
glutInitDisplayMode(((estado.doubleBuffer) ? GLUT_DOUBLE : GLUT_SINGLE) | GLUT_RGB);
if (glutCreateWindow("No Man's Pong") == GL_FALSE)
exit(1);
Init();
glutReshapeFunc(Reshape);
glutDisplayFunc(Draw);
// Callbacks de teclado
glutKeyboardFunc(Key);
glutKeyboardUpFunc(KeyUp);
glutMainLoop();
return 0;
}
Here's the ouput when pressing 'a':
Key Up a
Key Up a
Key Up a
Key Up a
Key Up a
Key Up a
Key Up a
......
Needless to say im not releasing 'a'.
Im using linux mint 17.3 and g++, shutting off key repeat or setting glutIgnoreKeyRepeat(true), stops this issue, but also makes glutKeyboardFunc execute only once per key press, and I realy don't want that.
Does anyone know how to fix this, or whats causing this?
I also compiled the same code under windows 8.1 and the keyUp only fires when there's an actual key release.
Just trying to draw a point using glut and glew for opengl version 4.3
my code
void Renderer(void)
{
glClear(GL_COLOR_BUFFER_BIT);
glBegin(GL_POINTS);
glPointSize(100);
glColor3f(255, 0, 0);
glVertex3d(10, 10, 0);
glEnd();
glFlush();
glutSwapBuffers();
}
is not rendering anything, can someone tell me what did i miss? here is full code:
#include <iostream>
using namespace std;
#include "vgl.h"
#include "LoadShaders.h"
enum VAO_IDs { Triangles, NumVAOS };
#define WIDTH 1024
#define HEIGHT 768
#define REFRESH_DELAY 10 //ms
//general
long frameCount = 0;
// mouse controls
int mouse_old_x, mouse_old_y;
int mouse_buttons = 0;
float rotate_x = 0.0, rotate_y = 0.0;
float translate_z = -3.0;
/////////////////////////////////////////////////////////////////////
//! Prototypes
/////////////////////////////////////////////////////////////////////
void keyboard(unsigned char key, int x, int y);
void mouse(int button, int state, int x, int y);
void motion(int x, int y);
void timerEvent(int value)
{
glutPostRedisplay();
glutTimerFunc(REFRESH_DELAY, timerEvent, frameCount++);
}
void init (void)
{
// default initialization
glClearColor(0.0, 0.0, 0.0, 1.0);
glDisable(GL_DEPTH_TEST);
// viewport
glViewport(0, 0, WIDTH, HEIGHT);
// projection
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(60.0, (GLfloat)WIDTH / (GLfloat)HEIGHT, 1, 10000.0);
}
void Renderer(void)
{
glClear(GL_COLOR_BUFFER_BIT);
glBegin(GL_POINTS);
glPointSize(100);
glColor3f(255, 0, 0);
glVertex3d(10, 10, 0);
glEnd();
glFlush();
glutSwapBuffers();
}
int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGBA);
glutInitWindowSize(WIDTH, HEIGHT);
glutInitContextVersion(4, 3);
glutInitContextProfile(GLUT_CORE_PROFILE);
glutCreateWindow("The Abyss");
glutKeyboardFunc(keyboard);
glutMotionFunc(motion);
glutMouseFunc(mouse);
glutTimerFunc(REFRESH_DELAY, timerEvent, frameCount);
if (glewInit()) //i guess this is true on failure
{
cerr << "Error initializing glew, Program aborted." << endl;
exit(EXIT_FAILURE);
}
//Init First
init();
//Init callback for Rendering
glutDisplayFunc(Renderer);
//Main Loop
glutMainLoop();
exit(EXIT_SUCCESS);
}
////////////////////////////////////////////////////////////////////////
//!Mouse and keyboard functionality
////////////////////////////////////////////////////////////////////////
void keyboard(unsigned char key, int /*x*/, int /*y*/)
{
switch (key)
{
case (27) :
exit(EXIT_SUCCESS);
break;
}
}
void mouse(int button, int state, int x, int y)
{
if (state == GLUT_DOWN)
{
mouse_buttons |= 1<<button;
}
else if (state == GLUT_UP)
{
mouse_buttons = 0;
}
mouse_old_x = x;
mouse_old_y = y;
}
void motion(int x, int y)
{
float dx, dy;
dx = (float)(x - mouse_old_x);
dy = (float)(y - mouse_old_y);
if (mouse_buttons & 1)
{
rotate_x += dy * 0.2f;
rotate_y += dx * 0.2f;
}
else if (mouse_buttons & 4)
{
translate_z += dy * 0.01f;
}
mouse_old_x = x;
mouse_old_y = y;
}
glutInitContextVersion(4, 3);
glutInitContextProfile(GLUT_CORE_PROFILE);
You have requested a Core context. You need to:
Specify a vertex and fragment shader. There are no freebies in Core.
Stop using deprecated functionality like glBegin() and glMatrixMode().
Start using VBOs to submit your geometry.
Start using glDrawArrays() and friends to draw your geometry.
I'm working on porting my open source particle engine test from SDL to SDL + OpenGL. I've managed to get it compiling, and running, but the screen stays black no matter what I do.
main.cpp:
#include "glengine.h"
int WINAPI WinMain(
HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow
)
{
//Create a glengine instance
ultragl::glengine *gle = new ultragl::glengine();
if(gle->init())
gle->run();
else
std::cout << "glengine initializiation failed!" << std::endl;
//If we can't initialize, or the lesson has quit we delete the instance
delete gle;
return 0;
};
glengine.h:
//we need to include window first because GLee needs to be included before GL.h
#include "window.h"
#include <math.h> // Math Library Header File
#include <vector>
#include <stdio.h>
using namespace std;
namespace ultragl
{
class glengine
{
protected:
window m_Window; ///< The window for this lesson
unsigned int m_Keys[SDLK_LAST]; ///< Stores keys that are pressed
float piover180;
virtual void draw();
virtual void resize(int x, int y);
virtual bool processEvents();
void controls();
private:
/*
* We need a structure to store our vertices in, otherwise we
* just had a huge bunch of floats in the end
*/
struct Vertex
{
float x, y, z;
Vertex(){}
Vertex(float x, float y, float z)
{
this->x = x;
this->y = y;
this->z = z;
}
};
struct particle
{
public :
double angle;
double speed;
Vertex v;
int r;
int g;
int b;
int a;
particle(double angle, double speed, Vertex v, int r, int g, int b, int a)
{
this->angle = angle;
this->speed = speed;
this->v = v;
this->r = r;
this->g = g;
this->b = b;
this->a = a;
}
particle()
{
}
};
particle p[500];
float particlesize;
public:
glengine();
~glengine();
virtual void run();
virtual bool init();
void glengine::test2(int num);
void glengine::update();
};
};
window.h:
#include <string>
#include <iostream>
#include "GLee/GLee.h"
#include <SDL/SDL.h>
#include <SDL/SDL_opengl.h>
#include <GL/glu.h>
using namespace std;
namespace ultragl
{
class window
{
private:
int w_height;
int w_width;
int w_bpp;
bool w_fullscreen;
string w_title;
public:
window();
~window();
bool createWindow(int width, int height, int bpp, bool fullscreen, const string& title);
void setSize(int width, int height);
int getHeight();
int getWidth();
};
};
glengine.cpp (the main one to look at):
#include "glengine.h"
namespace ultragl{
glengine::glengine()
{
piover180 = 0.0174532925f;
}
glengine::~glengine()
{
}
void glengine::resize(int x, int y)
{
std::cout << "Resizing Window to " << x << "x" << y << std::endl;
if (y <= 0)
{
y = 1;
}
glViewport(0,0,x,y);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45.0f,(GLfloat)x/(GLfloat)y,1.0f,100.0f);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
bool glengine::processEvents()
{
SDL_Event event;
while (SDL_PollEvent(&event))//get all events
{
switch (event.type)
{
// Quit event
case SDL_QUIT:
{
// Return false because we are quitting.
return false;
}
case SDL_KEYDOWN:
{
SDLKey sym = event.key.keysym.sym;
if(sym == SDLK_ESCAPE) //Quit if escape was pressed
{
return false;
}
m_Keys[sym] = 1;
break;
}
case SDL_KEYUP:
{
SDLKey sym = event.key.keysym.sym;
m_Keys[sym] = 0;
break;
}
case SDL_VIDEORESIZE:
{
//the window has been resized so we need to set up our viewport and projection according to the new size
resize(event.resize.w, event.resize.h);
break;
}
// Default case
default:
{
break;
}
}
}
return true;
}
bool glengine::init()
{
srand( time( NULL ) );
for(int i = 0; i < 500; i++)
p[i] = particle(0, 0, Vertex(0.0f, 0.0f, 0.0f), 0, 0, 0, 0);
if (!m_Window.createWindow(640, 480, 32, false, "Paricle Test GL"))
{
return false;
}
particlesize = 0.01;
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
glEnable(GL_BLEND);
glBlendFunc(GL_ONE , GL_ONE_MINUS_SRC_ALPHA);
return true;
}
void glengine::test2(int num)
{
glPushMatrix();
glTranslatef(p[num].v.x, p[num].v.y, p[num].v.z);
glBegin(GL_QUADS);
glColor4i(p[num].r, p[num].g, p[num].b, p[num].a); // Green for x axis
glVertex3f(-particlesize, -particlesize, particlesize);
glVertex3f( particlesize, -particlesize, particlesize);
glVertex3f( particlesize, particlesize, particlesize);
glVertex3f(-particlesize, particlesize, particlesize);
glEnd();
glPopMatrix();
}
void glengine::draw()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Clear Screen And Depth Buffer
glLoadIdentity(); // Reset The Current Modelview Matrix
gluLookAt(0, 5, 20, 0, 0, 0, 0, 0, 0);
for(int i = 0; i < 500; i++)
test2(i);
}
void glengine::update()
{
for(int i = 0; i < 500; i++)
{
if(p[i].a <= 0)
p[i] = particle(5 + rand() % 360, (rand() % 10) * 0.1, Vertex(0.0f, 0.0f, 0.0f), 0, 255, 255, 255);
else
p[i].a -= 1;
p[i].v.x += (sin(p[i].angle * (3.14159265/180)) * p[i].speed);
p[i].v.y -= (cos(p[i].angle * (3.14159265/180)) * p[i].speed);
}
}
void glengine::run()
{
while(processEvents())
{
update();
draw();
SDL_GL_SwapBuffers();
}
}
};
And finally window.cpp:
#include "window.h"
namespace ultragl
{
window::window(): w_width(0), w_height(0), w_bpp(0), w_fullscreen(false)
{
}
window::~window()
{
SDL_Quit();
}
bool window::createWindow(int width, int height, int bpp, bool fullscreen, const string& title)
{
if( SDL_Init( SDL_INIT_VIDEO ) != 0 )
return false;
w_height = height;
w_width = width;
w_title = title;
w_fullscreen = fullscreen;
w_bpp = bpp;
//Set lowest possiable values.
SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 5);
SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 5);
SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 5);
SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, 5);
SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 16);
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
//Set title.
SDL_WM_SetCaption(title.c_str(), title.c_str());
// Flags tell SDL about the type of window we are creating.
int flags = SDL_OPENGL;
if(fullscreen == true)
flags |= SDL_FULLSCREEN;
// Create window
SDL_Surface * screen = SDL_SetVideoMode( width, height, bpp, flags );
if(screen == 0)
return false;
//SDL doesn't trigger off a ResizeEvent at startup, but as we need this for OpenGL, we do this ourself
SDL_Event resizeEvent;
resizeEvent.type = SDL_VIDEORESIZE;
resizeEvent.resize.w = width;
resizeEvent.resize.h = height;
SDL_PushEvent(&resizeEvent);
return true;
}
void window::setSize(int width, int height)
{
w_height = height;
w_width = width;
}
int window::getHeight()
{
return w_height;
}
int window::getWidth()
{
return w_width;
}
};
Anyway, I really need to finish this, but I've already tried everything I could think of. I tested the glengine file many different ways to where it looked like this at one point:
#include "glengine.h"
#include "SOIL/SOIL.h"
#include "SOIL/stb_image_aug.h"
#include "SOIL/image_helper.h"
#include "SOIL/image_DXT.h"
namespace ultragl{
glengine::glengine()
{
piover180 = 0.0174532925f;
}
glengine::~glengine()
{
}
void glengine::resize(int x, int y)
{
std::cout << "Resizing Window to " << x << "x" << y << std::endl;
if (y <= 0)
{
y = 1;
}
glViewport(0,0,x,y);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45.0f,(GLfloat)x/(GLfloat)y,1.0f,1000.0f);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
bool glengine::processEvents()
{
SDL_Event event;
while (SDL_PollEvent(&event))//get all events
{
switch (event.type)
{
// Quit event
case SDL_QUIT:
{
// Return false because we are quitting.
return false;
}
case SDL_KEYDOWN:
{
SDLKey sym = event.key.keysym.sym;
if(sym == SDLK_ESCAPE) //Quit if escape was pressed
{
return false;
}
m_Keys[sym] = 1;
break;
}
case SDL_KEYUP:
{
SDLKey sym = event.key.keysym.sym;
m_Keys[sym] = 0;
break;
}
case SDL_VIDEORESIZE:
{
//the window has been resized so we need to set up our viewport and projection according to the new size
resize(event.resize.w, event.resize.h);
break;
}
// Default case
default:
{
break;
}
}
}
return true;
}
bool glengine::init()
{
srand( time( NULL ) );
for(int i = 0; i < 500; i++)
p[i] = particle(0, 0, Vertex(0.0f, 0.0f, 0.0f), 0, 0, 0, 0);
if (!m_Window.createWindow(640, 480, 32, false, "Paricle Test GL"))
{
return false;
}
particlesize = 10.01;
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
glEnable(GL_BLEND);
glBlendFunc(GL_ONE , GL_ONE_MINUS_SRC_ALPHA);
return true;
}
void glengine::test2(int num)
{
//glPushMatrix();
//glTranslatef(p[num].v.x, p[num].v.y, p[num].v.z);
glColor4i(255, 255, 255, 255);
glBegin(GL_QUADS);
glNormal3f( 0.0f, 0.0f, 1.0f);
glVertex3f(-particlesize, -particlesize, particlesize);
glVertex3f( particlesize, -particlesize, particlesize);
glVertex3f( particlesize, particlesize, particlesize);
glVertex3f(-particlesize, particlesize, particlesize);
glEnd();
// Back Face
glBegin(GL_QUADS);
glNormal3f( 0.0f, 0.0f,-1.0f);
glVertex3f(-particlesize, -particlesize, -particlesize);
glVertex3f(-particlesize, particlesize, -particlesize);
glVertex3f( particlesize, particlesize, -particlesize);
glVertex3f( particlesize, -particlesize, -particlesize);
glEnd();
// Top Face
glBegin(GL_QUADS);
glNormal3f( 0.0f, 1.0f, 0.0f);
glVertex3f(-particlesize, particlesize, -particlesize);
glVertex3f(-particlesize, particlesize, particlesize);
glVertex3f( particlesize, particlesize, particlesize);
glVertex3f( particlesize, particlesize, -particlesize);
glEnd();
// Bottom Face
glBegin(GL_QUADS);
glNormal3f( 0.0f,-1.0f, 0.0f);
glVertex3f(-particlesize, -particlesize, -particlesize);
glVertex3f( particlesize, -particlesize, -particlesize);
glVertex3f( particlesize, -particlesize, particlesize);
glVertex3f(-particlesize, -particlesize, particlesize);
glEnd();
// Right face
glBegin(GL_QUADS);
glNormal3f( 1.0f, 0.0f, 0.0f);
glVertex3f( particlesize, -particlesize, -particlesize);
glVertex3f( particlesize, particlesize, -particlesize);
glVertex3f( particlesize, particlesize, particlesize);
glVertex3f( particlesize, -particlesize, particlesize);
glEnd();
// Left Face
glBegin(GL_QUADS);
glNormal3f(-1.0f, 0.0f, 0.0f);
glVertex3f(-particlesize, -particlesize, -particlesize);
glVertex3f(-particlesize, -particlesize, particlesize);
glVertex3f(-particlesize, particlesize, particlesize);
glVertex3f(-particlesize, particlesize, -particlesize);
glEnd();
//glPopMatrix();
}
void glengine::draw()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Clear Screen And Depth Buffer
glLoadIdentity(); // Reset The Current Modelview Matrix
gluLookAt(0, 5, 20, 0, 0, 0, 0, 1, 0);
for(int i = 0; i < 500; i++)
test2(i);
}
void glengine::update()
{
for(int i = 0; i < 500; i++)
{
if(p[i].a <= 0)
p[i] = particle(5 + rand() % 360, (rand() % 10) * 0.1, Vertex(0.0f, 0.0f, -5.0f), 0, 255, 255, 255);
else
p[i].a -= 1;
p[i].v.x += (sin(p[i].angle * (3.14159265/180)) * p[i].speed);
p[i].v.y -= (cos(p[i].angle * (3.14159265/180)) * p[i].speed);
}
}
void glengine::run()
{
while(processEvents())
{
update();
draw();
SDL_GL_SwapBuffers();
}
}
};
It still didn't work. I'm really at my wits end on this one.
I haven't checked your code, but one thing I always do when debugging this kind of problems is to set the clear color to something colorful like (1, 0, 1) or so.
This will help you see if the problem is that your drawn object is completely black or if it's not drawn at all.
EDIT:
As someone mentioned in the comment: It also shows if you have a correct GL context if the clear operation clears to the right color or if it stays black.
Okay, I managed to fix it using a lot of your suggestions, and some other source code I had laying around. Turns out the problem was from 3 different lines.
particlesize = 0.01; should have been bigger: particlesize = 1.01;
glColor4i(255, 255, 255, 255) was turning the cube the same color as the clear color because I was using it wrong. I couldn't figure out how to use it right, so I'm using glColor4f(0.0f,1.0f,1.0f,0.5f) instead, and that works.
Last of all gluLookAt(0, 5, 20, 0, 0, 0, 0, 0, 0) needed to be gluLookAt(0, 5, 20, 0, 0, 0, 0, 1, 0)
Thank you all for your help, and your time.
You're not checking the return values of the SDL-GL-SetAttribute() calls.
And is 5/5/5/5 20-bpp color supported by your video card?
Check OpenGL for error states. Use glslDevil, glIntercept or gDebugger. Check the glGetError function. Can you test whether SDL actually acquired a device context?
Does the Window reflect changes in the glClearColor call? Don't use 0.5 as an alpha value in glClearColor.
Try these suggestions and report back with a minimal example as Simucal suggested.