I'm making a particle fountain in openGL, I have the particles functioning properly. I decided to add a plane to make it look like they are bouncing off from it. What I'm trying to get is something like this
Unfortunately what I'm getting is this
the plain doesn't seem to be appearing at all. I tried messing with the co-ordinates and that doesn't seem to do anything. This is the image I'm using as the texture, it's a 256 X 256 24bit bmp.
I load the texture in the init function, then call it before I render the particles in the following function
void Load_Plane(){
glEnable(GL_BLEND);
glBlendFunc(GL_ONE_MINUS_SRC_ALPHA, GL_SRC_ALPHA);
glColor4f(0.0f, 0.2f, 0.2f, 0.5f);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, txPlane);
glBegin(GL_QUADS);
glNormal3f(-10.0f, 0.0f, -10.0f);
glTexCoord2f(0.0f, 0.0f);
glVertex3f(-10.0f, 0.0f, 10.0f);
glTexCoord2f(1.0f, 0.0f);
glVertex3f( 10.0f, 0.0f, 10.0f);
glTexCoord2f(1.0f, 1.0f);
glVertex3f( 10.0f, 0.0f, -10.0f);
glTexCoord2f(0.0f, 1.0f);
glVertex3f(-10.0f, 0.0f, -10.0f);
glEnd();
}
full code
// particle_fountain.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include<stdlib.h>
#include <stdio.h>
#include<Windows.h>
#include <time.h>
#include <GL\glut.h>
#include<GL\GLU.h>
#define MAX_PARTICLES 200 //max number of particles
#define MAX_BOUNCE_COUNT 5 //number of times a particle should bounce
#define MAX_PARTICLE_AGE 95
//Colours
float R = 0.8f;
float G = 0.2f;
float B = 0.0f;
float cR = 0.001f;
float cG = 0.002f;
float cB = 0.003f;
float Size = 0.02f; //size for points
GLuint txParticle;
GLuint txPlane;
struct PARTICLE {
float X,Y,Z; // Current position
float sX,sY,sZ; // Current Speed/Movement
float tX,tY,tZ; // Target Speed/Movement
float R,B,G; // Particle Colour
bool Active; // Is particle Active
int Age; // Age of the particle
int MaxAge; // Maximum Age before particle dies
int BounceCount;
} Particles[MAX_PARTICLES];
void Init_Particles();
void Activate_Particles();
void Adjust_Particles();
void Render_Particles();
bool LoadBitmapTexture(char * FileName, GLuint &texid);
void timer(int extra);
void Load_Plane();
void DrawGLscene();
void Reshape(GLsizei w, GLsizei h);
int main(int argc, char** argv){
glutInit(&argc,argv);
glutInitDisplayMode( GLUT_RGBA| GLUT_DOUBLE );
glutInitWindowSize( 640, 480 );
glutCreateWindow("Particle fountain");
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glFrustum(-1.0, 1.0, -1.0, 1.0, 1.0, 10.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslatef(0.0, -0.9, -3.0);
Init_Particles();
glutDisplayFunc(DrawGLscene);
glutTimerFunc(0, timer, 0);
glutMainLoop();
}
void timer(int extra)
{
glutPostRedisplay();
glutTimerFunc(20, timer, 0);
}
void Load_Plane(){
glEnable(GL_BLEND);
glBlendFunc(GL_ONE_MINUS_SRC_ALPHA, GL_SRC_ALPHA);
glColor4f(0.0f, 0.2f, 0.2f, 0.5f);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, txPlane);
glBegin(GL_QUADS);
glNormal3f(-10.0f, 0.0f, -10.0f);
glTexCoord2f(0.0f, 0.0f);
glVertex3f(-10.0f, 0.0f, 10.0f);
glTexCoord2f(1.0f, 0.0f);
glVertex3f( 10.0f, 0.0f, 10.0f);
glTexCoord2f(1.0f, 1.0f);
glVertex3f( 10.0f, 0.0f, -10.0f);
glTexCoord2f(0.0f, 1.0f);
glVertex3f(-10.0f, 0.0f, -10.0f);
glEnd();
}
void DrawGLscene(){
Load_Plane();
glPushMatrix();
glScalef(1.0f, -1.0f, 1.0f);
Render_Particles();
glPopMatrix();
Render_Particles();
}
void Init_Particles(){
LoadBitmapTexture("./Particle.bmp", txParticle); //load the particle texture
LoadBitmapTexture("./Plain.bmp",txPlane); //load the plain texture
int p;
srand((int)time(NULL));
for(p=0; p<MAX_PARTICLES; p++){
Particles[p].Active = FALSE;
Particles[p].tX = 0.0f;
Particles[p].tY = -0.1f;
Particles[p].tZ = 0.0f;
}
}
void Activate_Particles(){
int p;
for(p=0; p<MAX_PARTICLES; p++){
if(!Particles[p].Active){
// Start the particle at 0,0,0 origin
Particles[p].X = 0.0f;
Particles[p].Y = 0.0f;
Particles[p].Z = 0.0f;
// The following lines set a random speed value
Particles[p].sX = (((float)((rand() % 100) + 1)) /
1000.0f) - 0.05f;
Particles[p].sY = (((float)((rand() % 100) + 50)) /
500.0f);
Particles[p].sZ = (((float)((rand() % 100) + 1)) /
1000.0f) - 0.05f;
// We also activate the particle
Particles[p].Active = true;
// Set it's Age to zero
Particles[p].Age = 0;
// We also assign a max age to the particles
Particles[p].MaxAge = MAX_PARTICLE_AGE;
// We Also reset the bouncecount to zero
Particles[p].BounceCount = 0;
//Adding the colours
Particles[p].R = R;
Particles[p].G = G;
Particles[p].B = B;
R+=cR;
G+=cG;
B+=cB;
if(R>1.0f){R=1.0f; cR=-cR;}
if(R<0.0f){R=0.0f; cR=-cR;}
if(G>1.0f){G=1.0f; cG=-cG;}
if(G<0.0f){G=0.0f; cG=-cG;}
if(B>1.0f){B=1.0f; cB=-cB;}
if(B<0.0f){B=0.0f; cB=-cB;}
return;
}
}
}
void Adjust_Particles(){
int p;
for(p=0; p<MAX_PARTICLES; p++){
// We move the speed towards the target speed by 1/20 (5%)
Particles[p].sX+= (Particles[p].tX - Particles[p].sX) / 20.0f;
Particles[p].sY+= (Particles[p].tY - Particles[p].sY) / 20.0f;
Particles[p].sZ+= (Particles[p].tZ - Particles[p].sZ) / 20.0f;
// Then we adjust the position of
// the particle by the new speed
Particles[p].X+= Particles[p].sX;
Particles[p].Y+= Particles[p].sY;
Particles[p].Z+= Particles[p].sZ;
// Now for the bounce code.
if(Particles[p].Y < 0.0f){
Particles[p].Y = 0.0f;
Particles[p].sY = -Particles[p].sY;
Particles[p].BounceCount++;
if(Particles[p].BounceCount > MAX_BOUNCE_COUNT){
Particles[p].Active = FALSE;
}
}
// And finally the age check
Particles[p].Age++;
if(Particles[p].Age > Particles[p].MaxAge){
Particles[p].Active = FALSE;
}
}
}
void Render_Particles(){
Activate_Particles();
Adjust_Particles();
glClear( GL_COLOR_BUFFER_BIT );
int p;
// Enable textures and bind our particle texture
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, txParticle);
// Disable Depth testing.
glDisable(GL_DEPTH_TEST);
// Enable blending
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_COLOR,GL_ONE);
for(p=0; p<MAX_PARTICLES; p++){
if(Particles[p].Active){
glColor4f(Particles[p].R,
Particles[p].G,
Particles[p].B, 1.0f);
glPushMatrix();
glTranslatef(Particles[p].X,
Particles[p].Y,
Particles[p].Z);
glBegin(GL_QUADS);
glNormal3f(0.0f, 0.0f, 1.0f);
glTexCoord2f(0.0f, 0.0f);
glVertex3f(-Size, -Size, 0.0f);
glTexCoord2f(1.0f, 0.0f);
glVertex3f(Size, -Size, 0.0f);
glTexCoord2f(1.0f, 1.0f);
glVertex3f(Size, Size, 0.0f);
glTexCoord2f(0.0f, 1.0f);
glVertex3f(-Size, Size, 0.0f);
glEnd();
glPopMatrix();
}
}
glEnable(GL_DEPTH_TEST);
glutSwapBuffers();
}
bool LoadBitmapTexture(char * FileName, GLuint &texid){
HBITMAP hBMP; // Handle Of The Bitmap
BITMAP BMP; // Bitmap Structure
glGenTextures(1, &texid); // Create The Texture
hBMP=(HBITMAP)LoadImage(GetModuleHandle(NULL),
FileName,
IMAGE_BITMAP, 0, 0,
LR_CREATEDIBSECTION | LR_LOADFROMFILE
);
if (!hBMP) // Does The Bitmap Exist?
return FALSE; // If Not Return False
GetObject(hBMP, sizeof(BMP), &BMP); // Get The Object
// hBMP: Handle To Graphics Object
// sizeof(BMP): Size Of Buffer For Object Information
// &BMP: Buffer For Object Information
glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
// Pixel Storage Mode (Word Alignment / 4 Bytes)
// Typical Texture Generation Using Data From The Bitmap
glBindTexture(GL_TEXTURE_2D, texid);// Bind To The Texture ID
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
GL_LINEAR); // Linear Min Filter
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,
GL_LINEAR); // Linear Mag Filter
glTexImage2D(GL_TEXTURE_2D, 0, 3, BMP.bmWidth, BMP.bmHeight,
0, GL_BGR_EXT, GL_UNSIGNED_BYTE, BMP.bmBits);
DeleteObject(hBMP); // Delete The Object
return TRUE; // Loading Was Successful
}
It could be that you're not clearing the depth buffer.
It doesn't affect any of the particles because you are disabling depth test when you render them, but when you render the plane, depth test is enabled, and since the depth buffer has not been cleared it has a spaz and doesn't render the plane.
Do
glClear(GL_DEPTH_BUFFER_BIT);
before you render the plane to clear the depth buffer.
EDIT:
This must be it-
You are calling
glClear(GL_COLOR_BUFFER_BIT);
after you render the plane. Look at your DrawGLScene function:
Load_Plane(); // you are drawing the plane here
glPushMatrix();
glScalef(1.0f, -1.0f, 1.0f);
Render_Particles(); // this function calls "glClear( GL_COLOR_BUFFER_BIT );"
// so anything that you rendered before is now removed.
glPopMatrix();
Render_Particles(); // same goes for here.
The solution would be to remove the call to glClear from your Render_Particles function,
and add it to the top of DrawGLScene:
(New DrawGLScene Code)
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
Load_Plane();
glPushMatrix();
glScalef(1.0f, -1.0f, 1.0f);
Render_Particles();
glPopMatrix();
Render_Particles();
EDIT #2:
You're calling glutSwapBuffers in the Render_Particles function.
Don't call it there. Call it at the end of DrawGLScene:
Related
I can load and render texture but there is a problem when I try to draw not only a texture but also a cube.
When I don't set cube's one (or more) side's color then it is white and background is fine.
When I set cube's one(or more) side's color by typing:
glColor3f(0.0f, 1.0f, 0.0f);
everything what is rendered changes it's color to this one.
I was looking for a mistake but I just couldn't find it.
main.cpp
/*This source code copyrighted by Lazy Foo' Productions (2004-2015)
and may not be redistributed without written permission.*/
//Using SDL, SDL OpenGL, standard IO, and, strings
#include <SDL.h>
#include <SDL_opengl.h>
#include <SDL_image.h>
#include <GL\GLU.h>
#include <stdio.h>
#include <string>
#include "TesterClass_Cubic.h"
//Screen dimension constants
const int SCREEN_WIDTH = 1366;
const int SCREEN_HEIGHT = 768;
//Starts up SDL, creates window, and initializes OpenGL
bool init();
//Initializes matrices and clear color
bool initGL();
//Input handler
void handleKeys(unsigned char key, int x, int y);
//Per frame update
void update();
//Renders quad to the screen
void render();
//Frees media and shuts down SDL
void close();
//The window we'll be rendering to
SDL_Window* gWindow = NULL;
//OpenGL context
SDL_GLContext gContext;
//Render flag
bool gRenderQuad = true;
GLuint tlo;
TesterClass_Cubic kostka(0.5, 0.0, 0.0, 0.0);
TesterClass_Cubic kostka_2(0.5, 0, 0, 0);
//BYĆ OSTROŻNYM Z UŻYCIEM, PONIEWAŻ ZAWSZE MUSI MIEĆ AKTUALNĄ WARTOŚĆ
//w innym wypadku funkcja resize może być wywołana dla nieakutalnych wymiarów okna
//zawsze jest updatowana w przypadku: zmiany rozmiaru okna(w funkcji resize)
int current_window_width = SCREEN_WIDTH;
int current_window_height = SCREEN_HEIGHT;
bool perspective_checker = true; // służy do przełączania perspektywy(pozycji kamery, funkcji gllookat), true-widok startowy zza bohatera, false- widok z gory
bool init()
{
//Initialization flag
bool success = true;
//Initialize SDL
if (SDL_Init(SDL_INIT_VIDEO) < 0)
{
printf("SDL could not initialize! SDL Error: %s\n", SDL_GetError());
success = false;
}
else
{
//Use OpenGL 2.1
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 2);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 1);
//Create window
gWindow = SDL_CreateWindow("SDL Tutorial", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, SCREEN_WIDTH, SCREEN_HEIGHT, SDL_WINDOW_OPENGL | SDL_WINDOW_SHOWN);
if (gWindow == NULL)
{
printf("Window could not be created! SDL Error: %s\n", SDL_GetError());
success = false;
}
else
{
//Create context
gContext = SDL_GL_CreateContext(gWindow);
if (gContext == NULL)
{
printf("OpenGL context could not be created! SDL Error: %s\n", SDL_GetError());
success = false;
}
else
{
//Use Vsync
if (SDL_GL_SetSwapInterval(1) < 0)
{
printf("Warning: Unable to set VSync! SDL Error: %s\n", SDL_GetError());
}
//Initialize OpenGL
if (!initGL())
{
printf("Unable to initialize OpenGL!\n");
success = false;
}
}
}
}
return success;
}
GLuint LoadTexture(char *filename)
{
SDL_Surface *surface;
GLuint textureid;
int mode;
surface = SDL_LoadBMP(filename);
// Or if you don't use SDL_image you can use SDL_LoadBMP here instead:
// surface = SDL_LoadBMP(filename);
// could not load filename
if (!surface)
{
return 0;
}
// create one texture name
glGenTextures(1, &textureid);
// tell opengl to use the generated texture name
glBindTexture(GL_TEXTURE_2D, textureid);
// this reads from the sdl surface and puts it into an opengl texture
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, surface->w, surface->h, 0, GL_BGR, GL_UNSIGNED_BYTE, surface->pixels);
// these affect how this texture is drawn later on...
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
// clean up
SDL_FreeSurface(surface);
//surface->w=dlugosc obrazka
return textureid;
}
void resize(int width, int height)
{
const float ar = (float)width / (float)height; //The width-to-height ratio
//Tell OpenGL how to convert from coordinates to pixel values
glViewport(0, 0, width, height); //specifies the part of the window to which OpenGL will draw(in pixels), convert from normalised to pixels
glMatrixMode(GL_PROJECTION); //Switch to setting the camera perspective
//Set the camera perspective
glLoadIdentity();//Reset the camera
glFrustum(-ar, ar, -1.0, 1.0, 2.0, 100.0);
if (perspective_checker)
{
gluLookAt(0, 2, 5, 0, 0, 0, 0, 1, 0);//widok standardowy-początkowy
}
else
{
gluLookAt(1.5, 4.7, 1.5, 1.5, 0, 1.5, 0, 0, -1);//widok "z góry"
}
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
SDL_GetWindowSize(gWindow, ¤t_window_width, ¤t_window_height);
}
void handleKeys(SDL_Event &event)
{
switch (event.key.keysym.sym)//get what key was pressed
{
case SDLK_d:
if (perspective_checker)
{
//kostka.move(0.1, 0, 0);
//obj.move(0.1, 0, 0);
}
break;
case SDLK_a:
if (perspective_checker)
{
//kostka.move(-0.1, 0, 0);
//obj.move(-0.1, 0, 0);
}
break;
case SDLK_q:
perspective_checker = !perspective_checker;
resize(current_window_width, current_window_height);
break;
}
}
void RysujTlo()
{
// tell opengl to use the generated texture name
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glBindTexture(GL_TEXTURE_2D, tlo);
glEnable(GL_TEXTURE_2D);
//Render quad
glBegin(GL_QUADS);
glTexCoord2f(0.0, 0.0);
glVertex3f(-4.5, 2.65, 0.0);
glTexCoord2f(0.0, 1.0);
glVertex3f(-6.0, -3.65, 0.0);
glTexCoord2f(1.0, 1.0);
glVertex3f(9.5, -3.65, 0.0);
glTexCoord2f(1.0, 0.0);
glVertex3f(4.5, 2.65, 0.0);
glEnd();
glPopMatrix();
glDisable(GL_TEXTURE_2D);
}
bool initGL()
{
bool success = true;
GLenum error = GL_NO_ERROR;
//Initialize Projection Matrix
const float ar = (float)SCREEN_WIDTH / (float)SCREEN_HEIGHT; //The width-to-height ratio
//Tell OpenGL how to convert from coordinates to pixel values
glViewport(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT); //specifies the part of the window to which OpenGL will draw(in pixels), convert from normalised to pixels
glMatrixMode(GL_PROJECTION); //Switch to setting the camera perspective
//Set the camera perspective
glLoadIdentity();//Reset the camera
glFrustum(-ar, ar, -1.0, 1.0, 2.0, 100.0);
gluLookAt(0, 2, 5, 0, 0, 0, 0, 1, 0); //pierwsze 3 wpsolrzedne to polozenie kamery,nastepne 3 to punkt na jaki patrzy kamera, nastepne 3 to kierunek gory kamery
//wektor [0,0,-1] o początku w punkcie (0,2,5), skierowany do tablicy,do monitora(dokładnie na punkt (0,0,0))
//gluLookAt(1.5, 4.7, 1.5, 1.5, 0, 1.5, 0, 0, -1); save best1
//gluLookAt(0, 3, 1.5, 0, 0, 1.5, 0, 0, -1); save best2
// /* Enable Z depth testing so objects closest to the viewpoint are in front of objects further away */
//enable depth - test to remove the hidden surface, and set the function used for the depth test.
glEnable(GL_COLOR_MATERIAL);
glShadeModel(GL_SMOOTH);
//setLight();
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LESS);
//glHint
//glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
/*In graphics rendering, there is often a trade - off between processing speed and visual quality.We can use glHint() to decide on the trade - off.
In this case, we ask for the best perspective correction, which may involve more processing.The default is GL_DONT_CARE.*/
//Check for error
error = glGetError();
if (error != GL_NO_ERROR)
{
printf("Error initializing OpenGL! %s\n", gluErrorString(error));
success = false;
}
//Initialize Modelview Matrix
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
//Check for error
error = glGetError();
if (error != GL_NO_ERROR)
{
printf("Error initializing OpenGL! %s\n", gluErrorString(error));
success = false;
}
//Initialize clear color
glClearColor(0.f, 0.f, 0.f, 0.f);
//Check for error
error = glGetError();
if (error != GL_NO_ERROR)
{
printf("Error initializing OpenGL! %s\n", gluErrorString(error));
success = false;
}
return success;
}
void handleKeys(unsigned char key, int x, int y)
{
//Toggle quad
if (key == 'q')
{
gRenderQuad = !gRenderQuad;
}
}
void update()
{
//No per frame update needed
}
void render()
{
//Clear color buffer
//kostka.drawCube();
//kostka_2.drawCube();
}
void setObjectPosition()
{
tlo = LoadTexture("background_front.bmp");
//kostka.setPosition(0, 0.3, 3.0);
//kostka_2.setPosition(3.2, 1.9, 0.5);
}
void close()
{
//Destroy window
SDL_DestroyWindow(gWindow);
gWindow = NULL;
//Quit SDL subsystems
SDL_Quit();
}
int main(int argc, char* args[])
{
//Start up SDL and create window
if (!init())
{
printf("Failed to initialize!\n");
}
else
{
//Main loop flag
bool quit = false;
//Event handler
SDL_Event e;
setObjectPosition();
//Enable text input
SDL_StartTextInput();
//While application is running
while (!quit)
{
//Handle events on queue
while (SDL_PollEvent(&e) != 0)
{
//User requests quit
if (e.type == SDL_QUIT)
{
quit = true;
}
//Handle keypress with current mouse position
else if (e.type == SDL_TEXTINPUT)
{
int x = 0, y = 0;
SDL_GetMouseState(&x, &y);
handleKeys(e.text.text[0], x, y);
}
else if (e.type == SDL_KEYDOWN)
{
//Select surfaces based on key press
handleKeys(e);
switch (e.key.keysym.sym)
{
case SDLK_ESCAPE:
quit = true;
break;
}
}
}
//Render quad
RysujTlo();
kostka.drawCube();
//render();
//Update screen
SDL_GL_SwapWindow(gWindow);
}
//Disable text input
SDL_StopTextInput();
}
//Free resources and close SDL
close();
return 0;
}
TesterClass_Cubic.cpp
#include "TesterClass_Cubic.h"
#include <SDL_opengl.h>
TesterClass_Cubic::TesterClass_Cubic()
{
}
TesterClass_Cubic::~TesterClass_Cubic()
{
}
TesterClass_Cubic::TesterClass_Cubic(double height, double red, double green, double blue) : m_height(height), m_r(red), m_g(green), m_b(blue)
{
m_x = 0.0;
m_y = 0.0;
m_z = 0.0;
m_angle = 0.0;
m_hide = true;
}
void TesterClass_Cubic::motion()
{
m_angle += 0.5;
if (m_angle > 360)
m_angle -= 360;
}
void TesterClass_Cubic::move(double dx, double dy, double dz)
{
m_x += dx;
m_y += dy;
m_z += dz;
}
void TesterClass_Cubic::setPosition(double x, double y, double z)
{
m_x = x;
m_y = y;
m_z = z;
}
void TesterClass_Cubic::drawCube()
{
if (m_hide)
{
glPushMatrix();
// angle, x-axis, y-axis, z-axis
// Render a color-cube consisting of 6 quads with different colors
// Reset the model-view matrix
glTranslated(m_x, m_y, m_z);
glRotated(m_angle, 1.0, 1.0, 1.0); // 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
glPopMatrix();
}
}
TesterClass_Cubic.h
#pragma once
class TesterClass_Cubic
{
private:
double m_width;
double m_height;
double m_x;
double m_y;
double m_z;
double m_angle;
double m_r;
double m_g;
double m_b;
bool m_hide;
public:
TesterClass_Cubic();
~TesterClass_Cubic();
TesterClass_Cubic(double height, double red, double green, double blue);
void drawCube();
void setPosition(double x, double y, double z);
void move(double dx, double dy, double dz);
void motion();
};
Im sorry for pasting the full code but Im not experienced user and not sure what do You need to help me.
What should I change in my code?
Here is what do i see
And here,how should the background look:
I'm trying to render a set of 200 RGB frames. For doing the same i'm creating a texture of height 416 and width 240. However i just get a black screen with the print statements working in the background.
Below is my code:
#include <stdio.h>
#include <stdlib.h>
#include "glew.h"
#include "glfw.h"
#include "glaux.h"
int index;
AUX_RGBImageRec texture1;
GLuint texture;
unsigned long long pos;
unsigned char *guibuffer;
HDC hDC = NULL;
void initGL(void)
{
int maxSz;
int maxwidth = 416;
int maxheight = 240;
if( !glfwInit() )
{
exit( EXIT_FAILURE );
}
// if( !glfwOpenWindow(4096, 2118, 0,0,0,0,0,0, GLFW_WINDOW ) )
if( !glfwOpenWindow(maxwidth, maxheight, 0,0,0,0,0,0, GLFW_WINDOW ) ) //GLFW_FULLSCREEN
{
glfwTerminate();
exit( EXIT_FAILURE );
}
glfwSetWindowTitle("sample");
glGetIntegerv(GL_MAX_TEXTURE_SIZE,&maxSz);
glClearColor(0.0f, 0.0f, 0.0f, 0.0f); // This Will Clear The Background Color To Black
glClearDepth(1.0); // Enables Clearing Of The Depth Buffer
glDepthFunc(GL_LESS); // The Type Of Depth Test To Do
glEnable(GL_DEPTH_TEST); // Enables Depth Testing
glShadeModel(GL_SMOOTH); // Enables Smooth Color Shading
glMatrixMode(GL_PROJECTION);
//glLoadIdentity();
hDC= wglGetCurrentDC();
#if 1
{ // TSS
HWND hCurrentWindow = GetActiveWindow();
char szTitle[256]="sample";
//SetWindowText(hCurrentWindow,szTitle );
// SetWindowLongA (hCurrentWindow , GWL_STYLE, (GetWindowLongA (hCurrentWindow , GWL_STYLE) & ~(WS_CAPTION)));
SetWindowLongA (hCurrentWindow, GWL_STYLE, (WS_VISIBLE));
}
#endif
glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_2D, texture);
}
int GL_Disply()
{
FILE *fptr=fopen("E:\\myRGB.rgb","rb");
fseek(fptr,pos,SEEK_SET);
fread(guibuffer,sizeof(unsigned char),sizeof(unsigned char)*416*240*3,fptr);
pos+=416*240*3;
texture1.sizeX =416;
texture1.sizeY =240;
texture1.data = guibuffer;
glDepthFunc(GL_ALWAYS);
glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_BLEND);
glDisable(GL_LIGHTING);
glEnable(GL_TEXTURE_2D);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, texture1.sizeX, texture1.sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);
glBegin(GL_QUADS);
//glNormal3f( 0.0f, 0.0f, 0.0f);
glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f, -1.0f, 0.0f);
glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f, -1.0f, 0.0f);
glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, 1.0f, 0.0f);
glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, 1.0f, 0.0f);
glEnd();
glDisable(GL_BLEND);
glEnable(GL_DEPTH_TEST);
// Swap front and back rendering buffers
glfwSwapBuffers();
glDeleteTextures(1, &texture);
}
int main(int argc, char *argv[])
{
initGL(); // GL initialization
/* CPU memory allocation using C - malloc */
guibuffer=(unsigned char*)malloc(sizeof(unsigned char)*416*240*3);
for(index=0;index<200;index++)
{
printf("frame %d displayed....\r",index);
GL_Disply();
}
return 0;
}
Can anyone please tell me where i'm going wrong?
You are not passing data (last parameter) to the glTexImage2D function. I guess you would want to pass data readed from your E:\myRGB.rgb file.
It may have something to do with the matrix stack. I think you want to be in glMatrixMode (GL_MODELVIEW) when you draw stuff, not GL_PROJECTION, and you may need to set up your matrices correctly. Though, glMatrixMode, glBegin, glEnd, glTexCoord, glVertex3f, is the old fixed function way of rendering. Using shaders is the modern way of rendering with OpenGL.
I'm writing a program that draws a rotating cube (with texture) in the middle of the screen followed by a small yellow sphere that orbits around the cube. The idea is to make the sphere as a spot light source that illuminates the cube.
Here is the problem: as you can see in the images below, I'm failing to achieve the spot light effect. It seems that the entire cube gets lighted:
I'm setting GL_SPOT_DIRECTION to be the cube position. I didn't set surface normals because I'm struggling to understand how to compute them for the cube, and I'm not sure a simple graphic application like this really requires it.
I'm sharing the code below:
main.cpp:
#include <QApplication>
#include "glwidget.h"
int main(int argc, char* argv[])
{
QApplication app(argc, argv);
GLWidget gl_widget;
gl_widget.show();
return app.exec();
}
GLWidget.h:
#pragma once
#include <QGLWidget>
#include <QImage>
class GLWidget : public QGLWidget
{
Q_OBJECT
public:
explicit GLWidget(QWidget* parent = 0);
virtual ~GLWidget();
void _draw_texture_cube(int w, int h);
void _draw_light();
/* OpenGL initialization, viewport resizing, and painting */
void initializeGL();
void paintGL();
void resizeGL( int width, int height);
/* enable the user to interact directly with the scene using the keyboard */
void keyPressEvent(QKeyEvent *e);
private:
int _width;
int _height;
QImage* _img;
GLuint _texture;
float xrot;
float yrot;
float zrot;
bool _light_on;
bool _must_rotate;
bool _pause_light;
GLfloat _light_pos[3];
GLfloat _cube_pos[3];
GLUquadricObj* _quadratic;
protected slots:
void _tick();
};
GLWidget.cpp:
#include "GLWidget.h"
#include <iostream>
#include <QKeyEvent>
#include <QTimer>
#include <cmath>
#define LIGHT_MOVEMENT_SPEED 20.0f // Degrees per second
#define pi 3.141592654f
GLWidget::GLWidget(QWidget *parent)
: QGLWidget(parent), _img(NULL), _light_on(true), _must_rotate(true),
_pause_light(false), _quadratic(NULL)
{
_width = 0;
_height = 0;
_texture = 0;
xrot = 0.f;
yrot = 0.f;
zrot = 0.f;
// Set central cube position
_cube_pos[0] = 0.0f;
_cube_pos[1] = 0.0f;
_cube_pos[2] = -7.0f;
// Set light position
_light_pos[0] = 0.5f;
_light_pos[1] = 0.5f;
_light_pos[2] = -7.0f;
}
GLWidget::~GLWidget()
{
if (_img)
delete _img;
glDeleteTextures(1, &_texture);
}
void GLWidget::_tick()
{
update(); // triggers paintGL()
QTimer::singleShot(33, this, SLOT(_tick()));
}
void GLWidget::initializeGL()
{
std::cout << "GLWidget::initializeGL" << std::endl;
glClearColor(0.0f, 0.0f, 0.0f, 1.0f); // Black Background
glEnable(GL_CULL_FACE);
/* Load bitmap */
glEnable(GL_TEXTURE_RECTANGLE_ARB);
glPixelStorei (GL_UNPACK_ALIGNMENT, 1);
if (!_img)
{
std::cout << "GLWidget::paintGL: loading image" << std::endl;
QImage tmp(":/crate.jpg");
if (tmp.isNull())
{
std::cout << "GLWidget::paintGL: !!! Failed QImage #1" << std::endl;
return;
}
_img = new QImage(QGLWidget::convertToGLFormat(tmp));
}
/* Convert bitmap into texture */
// Create The Texture
glGenTextures(1, &_texture);
// Typical Texture Generation Using Data From The Bitmap
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, _texture);
// Generate The Texture
glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0,
GL_RGBA, _img->width(), _img->height(), 0,
GL_RGBA, GL_UNSIGNED_BYTE, _img->bits());
if (glGetError() != GL_NO_ERROR)
{
std::cout << "GLWidget::paintGL: !!! Failed glTexImage2D" << std::endl;
return;
}
/* Setup lighting */
glShadeModel(GL_SMOOTH); //Smooth color shading
// Light properties
GLfloat AmbientLight[4] = {0.2, 0.2, 0.2, 1.0};
GLfloat DiffuseLight[4] = {0.8, 0.8, 0.8, 1.0}; // color
GLfloat SpecularLight[4] = {1.0, 1.0, 1.0, 1.0}; // bright
GLfloat SpecRef[] = {0.7f, 0.7f, 0.7f, 1.0f};
GLubyte Shine = 60.0;
//glLightModelfv(GL_LIGHT_MODEL_LOCAL_VIEWER, AmbientLight);
glLightfv(GL_LIGHT0, GL_AMBIENT, AmbientLight);
glLightfv(GL_LIGHT0, GL_DIFFUSE, DiffuseLight);
glLightfv(GL_LIGHT0, GL_SPECULAR, SpecularLight);
glLightfv(GL_LIGHT0, GL_POSITION, _light_pos);
glColorMaterial(GL_FRONT, GL_AMBIENT_AND_DIFFUSE);
glMaterialfv(GL_FRONT, GL_SPECULAR, SpecRef); // refletância do material
glMaterialf(GL_FRONT, GL_SHININESS, Shine); // concentração do brilho
glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, 0);
//glColorMaterial(GL_FRONT,GL_DIFFUSE);
glEnable(GL_COLOR_MATERIAL);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glEnable(GL_DEPTH_TEST);
// Sphere
_quadratic = gluNewQuadric(); // Create A Pointer To The Quadric Object
gluQuadricNormals(_quadratic, GLU_SMOOTH); // Create Smooth Normals
gluQuadricTexture(_quadratic, GL_TRUE); // Create Texture Coords
/* Start the timer */
_tick();
}
/* Draw the central cube with texture
*/
void GLWidget::_draw_texture_cube(int w, int h)
{
glPushMatrix();
glTranslatef(_cube_pos[0], _cube_pos[1], _cube_pos[2]);
glRotatef ( xrot, 1.0, 0.0, 0.0 );
glRotatef ( yrot, 0.0, 1.0, 0.0 );
glRotatef ( zrot, 0.0, 0.0, 1.0 );
glColor3f(1.0f, 1.0f, 1.0f);
glBegin(GL_QUADS); // Draw A Cube
// Front Face
glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, -1.0f, 1.0f);
glTexCoord2f(w, 0.0f); glVertex3f( 1.0f, -1.0f, 1.0f);
glTexCoord2f(w, h); glVertex3f( 1.0f, 1.0f, 1.0f);
glTexCoord2f(0.0f, h); glVertex3f(-1.0f, 1.0f, 1.0f);
// Back Face
glTexCoord2f(w, 0.0f); glVertex3f(-1.0f, -1.0f, -1.0f);
glTexCoord2f(w, h); glVertex3f(-1.0f, 1.0f, -1.0f);
glTexCoord2f(0.0f, h); glVertex3f( 1.0f, 1.0f, -1.0f);
glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f, -1.0f);
// Top Face
glTexCoord2f(0.0f, h); glVertex3f(-1.0f, 1.0f, -1.0f);
glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, 1.0f, 1.0f);
glTexCoord2f(w, 0.0f); glVertex3f( 1.0f, 1.0f, 1.0f);
glTexCoord2f(w, h); glVertex3f( 1.0f, 1.0f, -1.0f);
// Bottom Face
glTexCoord2f(w, h); glVertex3f(-1.0f, -1.0f, -1.0f);
glTexCoord2f(0.0f, h); glVertex3f( 1.0f, -1.0f, -1.0f);
glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f, 1.0f);
glTexCoord2f(w, 0.0f); glVertex3f(-1.0f, -1.0f, 1.0f);
// Right face
glTexCoord2f(w, 0.0f); glVertex3f( 1.0f, -1.0f, -1.0f);
glTexCoord2f(w, h); glVertex3f( 1.0f, 1.0f, -1.0f);
glTexCoord2f(0.0f, _img->height()); glVertex3f( 1.0f, 1.0f, 1.0f);
glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f, 1.0f);
// Left Face
glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, -1.0f, -1.0f);
glTexCoord2f(w, 0.0f); glVertex3f(-1.0f, -1.0f, 1.0f);
glTexCoord2f(w, h); glVertex3f(-1.0f, 1.0f, 1.0f);
glTexCoord2f(0.0f, h); glVertex3f(-1.0f, 1.0f, -1.0f);
glEnd();
glPopMatrix();
if (_must_rotate)
{
xrot += 0.6f;
yrot += 0.4f;
zrot += 0.8f;
}
}
/* Draw light source and light model (sphere)
*/
void GLWidget::_draw_light()
{
if (_light_on)
{
glEnable(GL_LIGHT0); // enable lights that we use
}
else
{
glDisable(GL_LIGHT0);
}
static float light_angle = 25.0f;
if (!_pause_light) // stop moving the light source
{
light_angle += LIGHT_MOVEMENT_SPEED * 0.1;
if (light_angle > 360.0f)
light_angle -= 360.0f;
}
/* Set light source position */
_light_pos[0] = 4.0f * (float) cos(light_angle * pi / 180.0f);
_light_pos[1] = 4.0f * (float) sin(light_angle * pi / 180.0f);
_light_pos[2] = -7;
glLightfv(GL_LIGHT0, GL_POSITION, _light_pos);
GLfloat SpotDir[] = {_cube_pos[0], _cube_pos[1], _cube_pos[2], 0.0 };
glLightfv(GL_LIGHT0, GL_SPOT_DIRECTION, SpotDir);
glLightf(GL_LIGHT0, GL_SPOT_CUTOFF, 150.0);
glLightf(GL_LIGHT0, GL_SPOT_EXPONENT, 15.0);
/* Set the light model position to be the same as the light source */
glPushMatrix();
glTranslatef(_light_pos[0], _light_pos[1], _light_pos[2]);
glColor3ub(255, 255, 0); // yellow
gluSphere(_quadratic, 0.2f, 32, 32); // draw sphere
glPopMatrix();
}
void GLWidget::paintGL()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Clear Screen And Depth Buffer
glMatrixMode ( GL_MODELVIEW ); // Select The Model View Matrix
glLoadIdentity(); // Reset The Current Modelview Matrix
/* Draw central cube */
glEnable(GL_TEXTURE_RECTANGLE_ARB);
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, _texture); // Select Our Texture
_draw_texture_cube(_img->width(), _img->height());
glDisable(GL_TEXTURE_RECTANGLE_ARB);
/* Draw light source and light model*/
_draw_light();
}
void GLWidget::resizeGL( int w, int h)
{
_width = w;
_height = h;
glViewport(0, 0, w, h);
glMatrixMode(GL_PROJECTION); // Select The Projection Matrix
glLoadIdentity(); // Reset The Projection Matrix
if (h == 0) // Calculate The Aspect Ratio Of The Window
gluPerspective ( 60, ( float ) w, 0.4, 500.0 );
else
gluPerspective ( 60, ( float ) w / ( float ) h, 0.4, 500.0 );
glMatrixMode ( GL_MODELVIEW ); // Select The Model View Matrix
glLoadIdentity ( ); // Reset The Model View Matrix
gluLookAt(0.0, 0.0, 2.0, // eye
0.0, 0.0, 0.0, // center
0.0, 1.0, 0.0); // up
}
void GLWidget::keyPressEvent(QKeyEvent *e)
{
switch (e->key())
{
case Qt::Key_L:
if (_light_on)
_light_on = false;
else
_light_on = true;
break;
case Qt::Key_P:
if (_pause_light)
_pause_light = false;
else
_pause_light = true;
break;
case Qt::Key_R:
if (_must_rotate)
_must_rotate = false;
else
_must_rotate = true;
break;
default:
break;
}
}
Lighting.pro:
QT += core gui opengl
SOURCES += \
GLWidget.cpp \
main.cpp
HEADERS += \
GLWidget.h
RESOURCES += \
resource.qrc
What needs to be changed in this application in order to achieve the desired effect?
You do not specify any normals for your cube faces. As OpenGL is a state machine, it will use the default surface normal for all vertices, hence all of your faces. As the normal vector is crucial for the lighting, all of your faces will be lit almost identical (vertex postions still are different, but the effect is weak).
You should also be aware that the fixed function lighting of OpenGL is done per vertex. If you really want to see a good spotlight on the cuve, you would either need to tessalate it so more vertices are used where the lighting equation is actually evaluated, or use shaders for per-fragment lighting.
I'm making a skybox in openGL c++, now I followed some tutorials on skyboxes, I have the image's all set up but my skybox doesn't get drawn at all! (I only see black opengl background)
So here is my code, what can be the problem? I'm looking at it for hours and can't find a thing, I'm new at openGL so if you spot any bad code please do tell! Thanks!
#include <iostream>
#include <stdlib.h>
#ifdef __APPLE__
#include <OpenGL/OpenGL.h>
#include <GLUT/glut.h>
#else
#include <GL/glut.h>
#endif
#include "imageloader.h"
using namespace std;
//angle of rotation
GLfloat xpos = 0, ypos = 0, zpos = 0, xrot = 0, yrot = 0, angle=0.0;
GLuint _textureId; //The OpenGL id of the texture
GLuint _skybox[5];
float lastx, lasty;
bool leftMouseButton = false;
float PI = 3.141592654f;
//Makes the image into a texture, and returns the id of the texture
GLuint __loadTexture(Image* image) {
GLuint textureId;
glGenTextures(1, &textureId);
glBindTexture(GL_TEXTURE_2D, textureId);
glTexImage2D(GL_TEXTURE_2D,
0,
GL_RGB,
image->width, image->height,
0,
GL_RGB,
GL_UNSIGNED_BYTE,
image->pixels);
return textureId;
}
GLuint __loadMipmappedTexture(Image *image) {
GLuint textureId;
glGenTextures(1, &textureId);
glBindTexture(GL_TEXTURE_2D, textureId);
gluBuild2DMipmaps(GL_TEXTURE_2D,
GL_RGB,
image->width, image->height,
GL_RGB,
GL_UNSIGNED_BYTE,
image->pixels);
return textureId;
}
void initRendering() {
glEnable(GL_DEPTH_TEST);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glEnable(GL_NORMALIZE);
glEnable(GL_COLOR_MATERIAL);
glEnable(GL_CULL_FACE);
glShadeModel (GL_SMOOTH); //set the shader to smooth shader
Image* image = loadBMP("artesis.bmp");
_textureId = __loadMipmappedTexture(image);
image = loadBMP("skybox/deep_ft.bmp");
_skybox[0] = __loadMipmappedTexture(image);
image = loadBMP("skybox/deep_lf.bmp");
_skybox[1] = __loadMipmappedTexture(image);
image = loadBMP("skybox/deep_bk.bmp");
_skybox[2] = __loadMipmappedTexture(image);
image = loadBMP("skybox/deep_rt.bmp");
_skybox[3] = __loadMipmappedTexture(image);
image = loadBMP("skybox/deep_up.bmp");
_skybox[4] = __loadMipmappedTexture(image);
image = loadBMP("skybox/deep_dn.bmp");
_skybox[5] = __loadMipmappedTexture(image);
delete image;
}
void handleResize(int w, int h) {
glViewport(0, 0, w, h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45.0, (double)w / (double)h, 1.0, 100.0);
glViewport (0, 0, w, h);
glMatrixMode(GL_MODELVIEW);
glutPostRedisplay();
}
void mouseMovement(int x, int y) {
if (leftMouseButton == true)
{
GLfloat diffx = (x-lastx)/20; //check the difference between the current x and the last x position
GLfloat diffy = (y-lasty)/20; //check the difference between the current y and the last y position
lastx = x; //set lastx to the current x position
lasty = y; //set lasty to the current y position
xrot += (float) diffy; //set the xrot to xrot with the addition of the difference in the y position
yrot += (float) diffx; //set the xrot to yrot with the addition of the difference in the x position
}
else if( leftMouseButton == false)
{
GLfloat diffx = x-lastx; //check the difference between the current x and the last x position
GLfloat diffy = y-lasty; //check the difference between the current y and the last y position
lastx = x; //set lastx to the current x position
lasty = y; //set lasty to the current y position
}
}
void mouseButtons(int button, int state, int x, int y) {
if ((state == GLUT_DOWN) && (button == GLUT_LEFT_BUTTON))
{
leftMouseButton = true;
}
else if ((state == GLUT_DOWN) && (button == GLUT_RIGHT_BUTTON))
{
leftMouseButton = false;
}
}
void drawGrid(float size, float step)
{
// disable lighting
glDisable(GL_LIGHTING);
glBegin(GL_LINES);
glColor3f(0.3f, 0.3f, 0.3f);
for(float i=step; i <= size; i+= step)
{
glVertex3f(-size, 0, i); // lines parallel to X-axis
glVertex3f( size, 0, i);
glVertex3f(-size, 0, -i); // lines parallel to X-axis
glVertex3f( size, 0, -i);
glVertex3f( i, 0, -size); // lines parallel to Z-axis
glVertex3f( i, 0, size);
glVertex3f(-i, 0, -size); // lines parallel to Z-axis
glVertex3f(-i, 0, size);
}
// x-axis
glColor3f(0.5f, 0, 0);
glVertex3f(-size, 0, 0);
glVertex3f( size, 0, 0);
// z-axis
glColor3f(0,0,0.5f);
glVertex3f(0, 0, -size);
glVertex3f(0, 0, size);
glEnd();
// enable lighting back
glEnable(GL_LIGHTING);
}
void keyboard (unsigned char key, int x, int y) {
float xrotrad, yrotrad;
switch(key) {
case 'a':
xrot += 1;
if(xrot > 360) xrot -= 360;
break;
case 'w':
xrot -= 1;
if(xrot < -360) xrot += 360;
break;
case 'z':
yrotrad = (yrot / 180 * PI);
xrotrad = (xrot / 180 * PI);
xpos += float(sin(yrotrad));
zpos -= float(cos(yrotrad));
ypos -= float(sin(xrotrad));
break;
case 's':
yrotrad = (yrot / 180 * PI);
xrotrad = (xrot / 180 * PI);
xpos -= float(sin(yrotrad));
zpos += float(cos(yrotrad));
ypos += float(sin(xrotrad));
break;
case 'd':
yrot += 1;
if (yrot >360) yrot -= 360;
break;
case 'q':
yrot -= 1;
if (yrot < -360)yrot += 360;
break;
case 27:
exit(0);
break;
}
}
void camera (void) {
glRotatef(xrot,1.0,0.0,0.0); //rotate our camera on teh x-axis (left and right)
glRotatef(yrot,0.0,1.0,0.0); //rotate our camera on the y-axis (up and down)
glTranslated(-xpos,-ypos,-zpos); //translate the screen to the position of our camera
}
void drawScene() {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
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_TEXTURE_WRAP_S, GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
GLfloat lightKa[] = {.0f, .0f, .0f, 1.0f}; // ambient light
GLfloat lightKd[] = {.9f, .9f, .9f, 1.0f}; // diffuse light
GLfloat lightKs[] = {1, 1, 1, 1}; // specular light
glLightfv(GL_LIGHT0, GL_AMBIENT, lightKa);
glLightfv(GL_LIGHT0, GL_DIFFUSE, lightKd);
glLightfv(GL_LIGHT0, GL_SPECULAR, lightKs);
// position the light
float lightPos[4] = {0, 10, 10, 0};
glLightfv(GL_LIGHT0, GL_POSITION, lightPos);
camera();
//call the skybox
// Store the current matrix
glPushMatrix();
// Reset and transform the matrix.
glLoadIdentity();
/* EDIT: I really dont know how to set gluLookAt, I guess it should be the camera positions??? */
gluLookAt(
0.0,0.0,0.0,
0.1, 0.0, 0.1,
0.0,1.0,0.0);
// Enable/Disable features
glPushAttrib(GL_ENABLE_BIT);
glEnable(GL_TEXTURE_2D);
glDisable(GL_DEPTH_TEST);
glDepthMask(false);
glDisable(GL_LIGHTING);
glDisable(GL_BLEND);
// Just in case we set all vertices to white.
glColor4f(1,1,1,1);
// Render the front quad
glBindTexture(GL_TEXTURE_2D, _skybox[0]);
glBegin(GL_QUADS);
glTexCoord2f(0, 0); glVertex3f( 0.5f, -0.5f, -0.5f );
glTexCoord2f(1, 0); glVertex3f( -0.5f, -0.5f, -0.5f );
glTexCoord2f(1, 1); glVertex3f( -0.5f, 0.5f, -0.5f );
glTexCoord2f(0, 1); glVertex3f( 0.5f, 0.5f, -0.5f );
glEnd();
// Render the left quad
glBindTexture(GL_TEXTURE_2D, _skybox[1]);
glBegin(GL_QUADS);
glTexCoord2f(0, 0); glVertex3f( 0.5f, -0.5f, 0.5f );
glTexCoord2f(1, 0); glVertex3f( 0.5f, -0.5f, -0.5f );
glTexCoord2f(1, 1); glVertex3f( 0.5f, 0.5f, -0.5f );
glTexCoord2f(0, 1); glVertex3f( 0.5f, 0.5f, 0.5f );
glEnd();
// Render the back quad
glBindTexture(GL_TEXTURE_2D, _skybox[2]);
glBegin(GL_QUADS);
glTexCoord2f(0, 0); glVertex3f( -0.5f, -0.5f, 0.5f );
glTexCoord2f(1, 0); glVertex3f( 0.5f, -0.5f, 0.5f );
glTexCoord2f(1, 1); glVertex3f( 0.5f, 0.5f, 0.5f );
glTexCoord2f(0, 1); glVertex3f( -0.5f, 0.5f, 0.5f );
glEnd();
// Render the right quad
glBindTexture(GL_TEXTURE_2D, _skybox[3]);
glBegin(GL_QUADS);
glTexCoord2f(0, 0); glVertex3f( -0.5f, -0.5f, -0.5f );
glTexCoord2f(1, 0); glVertex3f( -0.5f, -0.5f, 0.5f );
glTexCoord2f(1, 1); glVertex3f( -0.5f, 0.5f, 0.5f );
glTexCoord2f(0, 1); glVertex3f( -0.5f, 0.5f, -0.5f );
glEnd();
// Render the top quad
glBindTexture(GL_TEXTURE_2D, _skybox[4]);
glBegin(GL_QUADS);
glTexCoord2f(0, 1); glVertex3f( -0.5f, 0.5f, -0.5f );
glTexCoord2f(0, 0); glVertex3f( -0.5f, 0.5f, 0.5f );
glTexCoord2f(1, 0); glVertex3f( 0.5f, 0.5f, 0.5f );
glTexCoord2f(1, 1); glVertex3f( 0.5f, 0.5f, -0.5f );
glEnd();
// Render the bottom quad
glBindTexture(GL_TEXTURE_2D, _skybox[5]);
glBegin(GL_QUADS);
glTexCoord2f(0, 0); glVertex3f( -0.5f, -0.5f, -0.5f );
glTexCoord2f(0, 1); glVertex3f( -0.5f, -0.5f, 0.5f );
glTexCoord2f(1, 1); glVertex3f( 0.5f, -0.5f, 0.5f );
glTexCoord2f(1, 0); glVertex3f( 0.5f, -0.5f, -0.5f );
glEnd();
// Restore enable bits and matrix
glPopAttrib();
glPopMatrix();
glEnable(GL_DEPTH_TEST);
glEnable(GL_LIGHTING);
glEnable(GL_BLEND);
glDepthMask(true);
glClear(GL_DEPTH_BUFFER_BIT);
drawGrid(20, 1);
glutSwapBuffers(); //swap the buffers
}
void update(int value) {
angle++; //increase the angle
glutPostRedisplay(); //Tell GLUT that the display has changed
//Tell GLUT to call update again in 25 milliseconds
glutTimerFunc(25, update, 0);
}
int main(int argc, char** argv) {
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
glutInitWindowSize(800, 800);
glutCreateWindow("Block Position");
initRendering();
glutDisplayFunc(drawScene);
glutKeyboardFunc(keyboard);
glutIdleFunc(drawScene);
glutReshapeFunc(handleResize);
glutPassiveMotionFunc(mouseMovement);
glutTimerFunc(25, update, 0); //Add a timer
glutMouseFunc(mouseButtons);
glutMainLoop();
return 0;
}
If nothing is appearing at all, it may be because the sky box isn't in the scene because it's being culled (or not rendered) onto the screen.
In your code you specify 100.0 for the zFar:
gluPerspective(45.0, (double)w / (double)h, 1.0, 100.0);
Change the zFar value to accommodate for the size of the sky box (say 500.0) and it should appear.
You should start with minimal rendering, like no lightning, no face culling, just triangles in white color. So if you see white then at least your camera position is probably OK. Then you can enable culling, if all disappears then this is your problem - normals are in wrong directions. Then if all is OK, enable lighting, then texturing - and always check what changes.
so dont look at it too hard, but eliminate complexity - even check if simple trianlge will show up in the expected position.
I am trying to load and draw a 2d texture using OpenGL with GLFW and SOIL. I have this code, but I only get one solid color (which seems to come from the texture).
I have tested whether the .png loads with an example that came with SOIL, and it worked fine so there has to be some issue in my code.
This is my code:
#include <cstdio>
#include "GL/glfw.h"
#include "SOIL.h"
// function declarations
void drawscene();
void idlefunc();
void updatedisplay();
// global data
GLuint texture; // our example texture
int main(int argc, char **argv) {
if (!glfwInit()) {
fprintf(stderr, "Failed to initialize GLFW\n");
return 1;
}
if (!glfwOpenWindow(640, 480, 0, 0, 0, 0, 16, 0, GLFW_WINDOW)) {
fprintf(stderr, "Failed to open GLFW window\n");
return 1;
}
// enable vsync (if available)
glfwSwapInterval(1);
// load textures
texture = SOIL_load_OGL_texture(
"tex.png",
SOIL_LOAD_AUTO,
SOIL_CREATE_NEW_ID,
SOIL_FLAG_POWER_OF_TWO | SOIL_FLAG_MIPMAPS | SOIL_FLAG_DDS_LOAD_DIRECT
);
// check for an error during the texture loading
if (!texture) {
printf("SOIL loading error: '%s'\n", SOIL_last_result());
}
while (glfwGetWindowParam(GLFW_OPENED)) {
idlefunc();
}
// if we get here something went wrong
return 0;
}
// this function gets called every frame
void idlefunc() {
updatedisplay();
drawscene();
}
// set up te display
void updatedisplay() {
int screen_width, screen_height;
glfwGetWindowSize(&screen_width, &screen_height);
if (screen_height <= 0) screen_height = 1;
if (screen_width <= 0) screen_width = 1;
glViewport(0, 0, screen_width, screen_height);
glClearColor(0.02f, 0.02f, 0.02f, 0.0f);
glClear(GL_COLOR_BUFFER_BIT);
glEnable(GL_TEXTURE_2D);
glDisable(GL_DEPTH_TEST);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0.0, screen_width, screen_height, 0.0, 0.0, 1.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
// displacement trick for exact pixelization
glTranslatef(0.375f, 0.375f, 0.0f);
}
// draw the scene in this function
void drawscene() {
glBindTexture(GL_TEXTURE_2D, texture);
glPushMatrix();
glTranslatef(10.0f, 10.0f, 0);
glBegin(GL_QUADS);
glTexCoord2f(0.0f, 0.0f);
glVertex2f(0.0f, 0.0f);
glTexCoord2f(0.0f, 128.0f);
glVertex2f(0.0f, 128.0f);
glTexCoord2f(128.0f, 128.0f);
glVertex2f(128.0f, 128.0f);
glTexCoord2f(128.0f, 0.0f);
glVertex2f(128.0f, 0.0f);
glEnd();
glPopMatrix();
glfwSwapBuffers();
}
Found the issue (thanks to user786653). No matter the vertex coords, the tex coords are between 0.0 and 1.0. This is the fixed code:
// draw the scene in this function
void drawscene() {
glBindTexture(GL_TEXTURE_2D, texture);
glPushMatrix();
glTranslatef(10.0f, 10.0f, 0);
glBegin(GL_QUADS);
glTexCoord2f(0.0f, 0.0f);
glVertex2f(0.0f, 0.0f);
glTexCoord2f(0.0f, 1.0f);
glVertex2f(0.0f, 128.0f);
glTexCoord2f(1.0f, 1.0f);
glVertex2f(128.0f, 128.0f);
glTexCoord2f(1.0f, 0.0f);
glVertex2f(128.0f, 0.0f);
glEnd();
glPopMatrix();
glfwSwapBuffers();
}