I'm trying to display a spinning cube with 6 different textures (all jpg and jpeg) using SDL library. But the program only shows white squares only. Anyone can please explain what happened to these textures?
each function behavior
opengl_init(): init opengl settings
init(): init SDL settings including opengl_init()
clean_up(): runs right before program ends
RenewTexture(): here I want to map texture with this function
main(): about drawing vertexes and playing each frame with spinning function
const int window_width = 1024;
const int window_height = 1024;
const int SCREEN_BPP = 32;
SDL_Event event;
SDL_Window* win = NULL;
SDL_Renderer* renderer = NULL;
GLuint texId[6];
SDL_GLContext context;
/****** Name Space for Game Variables ******/
namespace var
{
int frame_start_time = 0;
int frame_current_time = 0;
int frame_count = 0;
}
/****** Initializes Core OpenGL Features ******/
bool opengl_init()
{
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_BLEND);
glEnable(GL_TEXTURE_2D);
glClearColor(0, 0, 0, 0);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45.0, (640.0 / 480.0), 0.1, 100.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
std::cout << glGetError << std::endl;
if (glGetError() != GL_NO_ERROR)
{
return false;
}
return true;
}
/****** Initializes SDL, OpenGL and Video and Window ******/
bool init()
{
//if (SDL_Init(SDL_INIT_EVERYTHING) < 0)
if (SDL_Init(SDL_INIT_VIDEO) < 0)
{
return false;
}
win = SDL_CreateWindow("WINDOW", 100, 100, window_width, window_height, SDL_WINDOW_OPENGL);
renderer = SDL_CreateRenderer(win, -1, SDL_RENDERER_ACCELERATED);
context = SDL_GL_CreateContext(win);
if (opengl_init() == false)
{
return false;
}
}
/* Removes objects before game closes */
void clean_up()
{
SDL_Quit();
}
void RenewTexture(SDL_Surface* tmpimg, int index) {
GLubyte* map = (GLubyte*)tmpimg->pixels;
glBindTexture(GL_TEXTURE_2D, texId[index]);
int w, h;
w = tmpimg->w;
h = tmpimg->h;
/*glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);*/
glTexImage2D(
GL_TEXTURE_2D, 0, GL_RGB,
w, h, 0,
GL_RGB, GL_UNSIGNED_BYTE,
map
);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
// glBindTexture(GL_TEXTURE_2D, texId[index]);
}
int main(int argc, char* args[])
{
std::vector<SDL_Surface*> image;
GLfloat rotation = 0.0f;
bool quit = false;
if (init() == false)
{
return 1;
}
const char* ImageNames[6] = { "res/KGU-logo.jpg", "res/Me.jpeg", "res/beach-1838501.jpg", "res/bench-560435.jpg", "res/wolf-1341881_1920.jpg", "res/spring-bird-2295434.jpg" };
for (int i = 0; i < 6; i++) {
SDL_RWops* tmprwop = SDL_RWFromFile(ImageNames[i], "rb");
SDL_Surface* tmpimg = IMG_LoadJPG_RW(tmprwop);
image.push_back(tmpimg);
}
for(int i=0;i<6;i++)
glGenTextures(1, &texId[i]);
/*SDL_Rect position;
position.x = 1;
position.y = 1;
position.h = 10;
position.w = 10;
SDL_RenderClear(renderer);
SDL_RenderCopy(renderer, SDL_CreateTextureFromSurface(renderer, image.at(0)), NULL, &position);
SDL_RenderPresent(renderer);*/
/****** Main Game Loop ******/
while (quit == false)
{
/****** Get Most Current Time ******/
var::frame_start_time = SDL_GetTicks();
/****** Draw Rectangle ******/
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
glTranslatef(0.0f, 0.0f, -6.0f);
glRotatef(rotation, 1.0f, 1.0f, 0.0f);
RenewTexture(image.at(0), 0);
glBegin(GL_QUADS);
glTexCoord2f(0.0, 0.0); glVertex2f(0, 0);
glTexCoord2f(1.0, 0.0); glVertex2f(550, 0);
glTexCoord2f(1.0, 1.0); glVertex2f(550, 550);
glTexCoord2f(0.0, 1.0); glVertex2f(0, 550);
glEnd();
RenewTexture(image.at(0), 0);
glBegin(GL_QUADS);
/* Cube Top */
//glColor4f(1.0f, 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);
RenewTexture(image.at(1), 1);
/* Cube Bottom */
//glColor4f(1.0f, 0.5f, 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);
RenewTexture(image.at(2), 2);
/* Cube Front */
//glColor4f(0.0f, 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);
RenewTexture(image.at(3), 3);
/* Cube Back */
//glColor4f(0.0f, 1.0f, 0.5f, 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);
RenewTexture(image.at(4), 4);
/* Cube Left Side */
//glColor4f(0.5f, 0.5f, 0.5f, 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);
RenewTexture(image.at(5), 5);
/* Cube Right Side */
//glColor4f(0.15f, 0.25f, 0.75f, 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();
rotation -= 0.5f;
/****** Check for Key & System input ******/
while (SDL_PollEvent(&event))
{
/****** Application Quit Event ******/
if (event.type == SDL_QUIT)
{
quit = true;
}
}
/****** Update Screen And Frame Counts ******/
SDL_GL_SwapWindow(win);
var::frame_count++;
var::frame_current_time = SDL_GetTicks();
/****** Frame Rate Handle ******/
if ((var::frame_current_time - var::frame_start_time) < (1000 / 60))
{
var::frame_count = 0;
SDL_Delay((1000 / 60) - (var::frame_current_time - var::frame_start_time));
}
}
clean_up();
return 0;
}
Edit
Solved via changing all glTexCoord3f() to glTexCoord2f() and it worked... my fault :D
additionaly, I misunterstood glEnable(GL_TEXTURE_3D) so changed to glEnable(GL_TEXTURE_2D), and checked all opengl errors via error check function
void errorcheck() {
int errormsg;
if ((errormsg = glGetError()) != GL_NO_ERROR)
{
std::cout << "glerror: " << errormsg << std::endl;
exit(0);
}
}
Related
I found a useful post at this site, where some code is used to load a BMP
This code should load the header, read out infos, go further, read data, generate texture and bin it. But it doesnt work. What am I doing wrong ?
Texture Declaration :
GLuint texture[1];
BMP Loading :
void LoadTexture(char *filename)
{
FILE * file = fopen(filename,"rb");
unsigned char header[54];
unsigned int dataPos;
unsigned int imageSize;
unsigned int width, height;
fread(header,1,54,file);
dataPos = *(int*)&(header[0x0A]);
imageSize = *(int*)&(header[0x22]);
width = *(int*)&(header[0x12]);
height = *(int*)&(header[0x16]);
if (imageSize==0) {
imageSize=width*height*3;
}
if (dataPos==0) {
dataPos=54;
}
unsigned char data[imageSize];
fseek(file, SEEK_SET, 53);
fread(data,1,imageSize,file);
fclose(file);
glActiveTexture(GL_TEXTURE1);
glGenTextures(1, texture[0]);
glBindTexture(GL_TEXTURE_2D, texture[0]);
glTexImage2D(GL_TEXTURE_2D, 0,GL_RGB, width, height, 0, GL_BGR, GL_UNSIGNED_BYTE, data);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
glGenerateMipmap(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, texture[0]);
}
EDIT : I printed out some values read from the header. The header seems to be read properly.
Drawing :
int DrawGLScene(GLvoid)
{
glLoadIdentity();
glEnable(GL_TEXTURE_2D);
glTranslatef(0.0f,0.0f,-5.0f);
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, texture[0]);
glBegin(GL_QUADS);
glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, -1.0f, 1.0f);
glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, -1.0f, 1.0f);
glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f, 1.0f, 1.0f);
glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f, 1.0f, 1.0f);
glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f, -1.0f);
glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f, 1.0f, -1.0f);
glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f, 1.0f, -1.0f);
glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f, -1.0f);
glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f, 1.0f, -1.0f);
glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, 1.0f, 1.0f);
glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, 1.0f, 1.0f);
glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f, 1.0f, -1.0f);
glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f, -1.0f, -1.0f);
glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f, -1.0f, -1.0f);
glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f, 1.0f);
glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f, 1.0f);
glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, -1.0f, -1.0f);
glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f, 1.0f, -1.0f);
glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f, 1.0f, 1.0f);
glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f, 1.0f);
glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, -1.0f, -1.0f);
glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f, 1.0f);
glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f, 1.0f, 1.0f);
glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f, 1.0f, -1.0f);
glEnd();
glFlush();
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
return 1;
}
Finally, after browsing the internet quite a lot, I found this working example :
#include <stdlib.h>
#include <string.h>
#include <GL/glut.h>
#include <GL/gl.h>
#include <GL/glu.h>
#include <stdio.h>
#include <math.h>
GLuint texture[2];
struct Image {
unsigned long sizeX;
unsigned long sizeY;
char *data;
};
typedef struct Image Image;
#define checkImageWidth 64
#define checkImageHeight 64
GLubyte checkImage[checkImageWidth][checkImageHeight][3];
void makeCheckImage(void){
int i, j, c;
for (i = 0; i < checkImageWidth; i++) {
for (j = 0; j < checkImageHeight; j++) {
c = ((((i&0x8)==0)^((j&0x8)==0)))*255;
checkImage[i][j][0] = (GLubyte) c;
checkImage[i][j][1] = (GLubyte) c;
checkImage[i][j][2] = (GLubyte) c;
}
}
}
int ImageLoad(char *filename, Image *image) {
FILE *file;
unsigned long size; // size of the image in bytes.
unsigned long i; // standard counter.
unsigned short int planes; // number of planes in image (must be 1)
unsigned short int bpp; // number of bits per pixel (must be 24)
char temp; // temporary color storage for bgr-rgb conversion.
// make sure the file is there.
if ((file = fopen(filename, "rb"))==NULL){
printf("File Not Found : %s\n",filename);
return 0;
}
// seek through the bmp header, up to the width/height:
fseek(file, 18, SEEK_CUR);
// read the width
if ((i = fread(&image->sizeX, 4, 1, file)) != 1) {
printf("Error reading width from %s.\n", filename);
return 0;
}
//printf("Width of %s: %lu\n", filename, image->sizeX);
// read the height
if ((i = fread(&image->sizeY, 4, 1, file)) != 1) {
printf("Error reading height from %s.\n", filename);
return 0;
}
//printf("Height of %s: %lu\n", filename, image->sizeY);
// calculate the size (assuming 24 bits or 3 bytes per pixel).
size = image->sizeX * image->sizeY * 3;
// read the planes
if ((fread(&planes, 2, 1, file)) != 1) {
printf("Error reading planes from %s.\n", filename);
return 0;
}
if (planes != 1) {
printf("Planes from %s is not 1: %u\n", filename, planes);
return 0;
}
// read the bitsperpixel
if ((i = fread(&bpp, 2, 1, file)) != 1) {
printf("Error reading bpp from %s.\n", filename);
return 0;
}
if (bpp != 24) {
printf("Bpp from %s is not 24: %u\n", filename, bpp);
return 0;
}
// seek past the rest of the bitmap header.
fseek(file, 24, SEEK_CUR);
// read the data.
image->data = (char *) malloc(size);
if (image->data == NULL) {
printf("Error allocating memory for color-corrected image data");
return 0;
}
if ((i = fread(image->data, size, 1, file)) != 1) {
printf("Error reading image data from %s.\n", filename);
return 0;
}
for (i=0;i<size;i+=3) { // reverse all of the colors. (bgr -> rgb)
temp = image->data[i];
image->data[i] = image->data[i+2];
image->data[i+2] = temp;
}
// we're done.
return 1;
}
Image * loadTexture(){
Image *image1;
// allocate space for texture
image1 = (Image *) malloc(sizeof(Image));
if (image1 == NULL) {
printf("Error allocating space for image");
exit(0);
}
if (!ImageLoad("NeHe.bmp", image1)) {
exit(1);
}
return image1;
}
void myinit(void)
{
glClearColor (0.5, 0.5, 0.5, 0.0);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LESS);
Image *image1 = loadTexture();
if(image1 == NULL){
printf("Image was not returned from loadTexture\n");
exit(0);
}
makeCheckImage();
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
// Create Texture
glGenTextures(2, texture);
glBindTexture(GL_TEXTURE_2D, texture[0]);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); //scale linearly when image bigger than texture
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR); //scale linearly when image smalled than texture
glTexImage2D(GL_TEXTURE_2D, 0, 3, image1->sizeX, image1->sizeY, 0,
GL_RGB, GL_UNSIGNED_BYTE, image1->data);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
glBindTexture(GL_TEXTURE_2D, texture[1]);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
glTexImage2D(GL_TEXTURE_2D, 0, 3, checkImageWidth,
checkImageHeight, 0, GL_RGB, GL_UNSIGNED_BYTE,&checkImage[0][0][0]);
glEnable(GL_TEXTURE_2D);
glShadeModel(GL_FLAT);
}
void display(void){
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glBindTexture(GL_TEXTURE_2D, texture[1]);
glutSolidTeapot(1.0);
glBindTexture(GL_TEXTURE_2D, texture[0]);
glBegin(GL_QUADS);
glTexCoord2f(0.0, 0.0);
glVertex3f(1.0, -1.0, 0.0);
glTexCoord2f(1.0, 0.0);
glVertex3f(1.0, 1.0, 0.0);
glTexCoord2f(1.0, 1.0);
glVertex3f(2.41421, 1.0, -1.41421);
glTexCoord2f(0.0, 1.0);
glVertex3f(2.41421, -1.0, -1.41421);
glEnd();
glutSwapBuffers();
}
void myReshape(int w, int h){
glViewport(0, 0, w, h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(60.0, 1.0*(GLfloat)w/(GLfloat)h, 1.0, 30.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslatef(0.0, 0.0, -3.6);
}
void keyboard (unsigned char key, int x, int y){
switch (key) {
case 27: // “esc” on keyboard
exit(0);
break;
default: // “a” on keyboard
break;
}
}
int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
glutCreateWindow("Texture Mapping - Programming Techniques");
myinit();
glutReshapeFunc (myReshape);
glutDisplayFunc(display);
glutKeyboardFunc(keyboard);
glutMainLoop();
return 0;
}
Review how you read data. dataPos, size and others may be set after reading the BMP. It's a relative position defined in the header of the image file.
And then review glTexImage2D(). Your are passing datainstead of dataPos.
My school uses windows computers but I only have a mac at home.
The code runs fine in windows but for some reason I get errors running it in xCode.
I wasn't sure which frameworks to include so I added GLKit, Cocoa, GLUT, and OpenGL.
Am I missing something??
I would like to get Xcode setup so I can work on homework with the same code that will work on windows.
Here is the code
#include <stdio.h>
#include <stdarg.h>
#include <math.h>
#define GL_GLEXT_PROTOTYPES
#ifdef __APPLE__
#include <GLUT/glut.h>
#else
#include <GL/glut.h>
#endif
#define GLUT_KEY_ESCAPE 27
const GLsizei windowWidth = 500;
const GLsizei windowHeight = 500;
GLfloat cubeRotateX = 45.0f;
GLfloat cubeRotateY = 45.0f;
bool keys[255];
GLvoid establishProjectionMatrix(GLsizei width, GLsizei height)
{
glViewport(0, 0, width, height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45.0f, (GLfloat)width / (GLfloat)height, 0.1f, 200.0f);
}
GLvoid initGL(GLsizei width, GLsizei height)
{
establishProjectionMatrix(width, height);
glShadeModel(GL_SMOOTH);
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
glEnable(GL_PERSPECTIVE_CORRECTION_HINT);
}
GLvoid displayFPS(GLvoid)
{
static long lastTime = glutGet(GLUT_ELAPSED_TIME);
static int loops = 0;
static GLfloat fps = 0.0f;
int newTime = glutGet(GLUT_ELAPSED_TIME);
if (newTime - lastTime > 100)
{
float newFPS = (float)loops / float(newTime - lastTime) * 1000.0f;
fps = (fps + newFPS) / 2.0f;
char title[80];
sprintf_s(title, "OpenGL Demo - %.2f", fps);
glutSetWindowTitle(title);
lastTime = newTime;
loops = 0;
}
loops++;
}
GLvoid drawScene(GLvoid)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslatef(0, 0, -5.0f);
glRotatef(cubeRotateX, 1.0, 0.0, 0.0);
glRotatef(cubeRotateY, 0.0, 1.0, 0.0);
glBegin(GL_QUADS);
glColor3f(0.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);
glVertex3f( 1.0f, 1.0f, 1.0f);
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.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();
glFlush();
glutSwapBuffers();
displayFPS();
}
GLboolean checkKeys(GLvoid)
{
const GLfloat speed = 1.0f;
if ( keys[GLUT_KEY_ESCAPE] )
return true;
if (keys[GLUT_KEY_LEFT])
cubeRotateY -= speed;
if (keys[GLUT_KEY_RIGHT])
cubeRotateY += speed;
if (keys[GLUT_KEY_UP])
cubeRotateX -= speed;
if (keys[GLUT_KEY_DOWN])
cubeRotateX += speed;
return false;
}
GLvoid timerLoop(int value)
{
if (checkKeys())
exit(0);
glutPostRedisplay();
glutTimerFunc(1, timerLoop, 0);
}
GLvoid keyboardCB(unsigned char key, int x, int y)
{
keys[key] = true;
}
GLvoid keyboardUpCB(unsigned char key, int x, int y)
{
keys[key] = false;
}
GLvoid keyboardSpecialCB(int key, int x, int y)
{
keys[key] = true;
}
GLvoid keyboardSpecialUpCB(int key, int x, int y)
{
keys[key] = false;
}
int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE);
int windowID = glutCreateWindow("OpenGL Cube Demo");
glutReshapeWindow(windowWidth, windowHeight);
initGL(windowWidth, windowHeight);
glutDisplayFunc(drawScene);
glutKeyboardFunc(keyboardCB);
glutKeyboardUpFunc(keyboardUpCB);
glutSpecialFunc(keyboardSpecialCB);
glutSpecialUpFunc(keyboardSpecialUpCB);
glutTimerFunc(1, timerLoop, 0);
glutMainLoop();
return 0;
}
Why does it work in visual studio and not in Xcode??
The errors from the compiler seem pretty clear. The superficial reason it doesn't work is because this code contains Windows-isms that are not portable.
C++ doesn't allow a typedef of void to indicate an empty parameter list. You have to use void itself. So, just changed those GLvoids to voids.
sprintf_s() is a Windows-specific function. You can replace it with snprintf(), but you have to add a parameter after the buffer which is the size of the buffer. So, replace this:
sprintf_s(title, ...);
with:
snprintf(title, sizeof(title), ...);
The exit() function is available cross-platform, but you have to include the right header. Add #include <stdlib.h> near the top of your file.
im creating a simple textured cube but im have a problem with the my keyboard functions i do not seem to interact,i want the cube to move in the x and y direction but its not moving,i used this function
void specialKeys( int key, int x, int y ) {
if (key == GLUT_KEY_RIGHT)
rotate_y += 5;
else if (key == GLUT_KEY_LEFT)
rotate_y -= 5;
else if (key == GLUT_KEY_UP)
rotate_x += 5;
else if (key == GLUT_KEY_DOWN)
rotate_x -= 5;
glutPostRedisplay();
}
and in my main function i used this code
glutSpecialFunc(specialKeys);
this is my whole code
#include <stdlib.h>
#include <GL/glut.h>
#include "RgbImage.h"
void specialKeys();
double rotate_y=0;
double rotate_x=0;
GLfloat xRotated, yRotated, zRotated;
GLuint texture[1]; // Storage For One Texture ( NEW )
void loadTextureFromFile(char *filename)
{
glClearColor (0.0, 0.0, 0.0, 0.0);
glShadeModel(GL_FLAT);
glEnable(GL_DEPTH_TEST);
RgbImage theTexMap( filename );
glGenTextures(1, &texture[0]); // Create The Texture
glBindTexture(GL_TEXTURE_2D, texture[0]);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
// Typical Texture Generation Using Data From The Bitmap
glTexImage2D(GL_TEXTURE_2D, 0, 3, theTexMap.GetNumCols(), theTexMap.GetNumRows(), 0, GL_RGB, GL_UNSIGNED_BYTE, theTexMap.ImageData() );
}
void drawScene(void)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, texture[0]);
glLoadIdentity();
glTranslatef(0.0,0.0,-5);
glRotatef(yRotated, 0, 1, 0);
glRotatef(zRotated, 0, 0, 1);
glBegin(GL_QUADS);
// Front Face
// Back Face
glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f, -1.0f);
glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f, 1.0f, -1.0f);
glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f, 1.0f, -1.0f);
glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f, -1.0f);
// Top Face
// Bottom Face
glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f, -1.0f, -1.0f);
glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f, -1.0f, -1.0f);
glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f, 1.0f);
glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f, 1.0f);
// Right face
glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, -1.0f, -1.0f);
glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f, 1.0f, -1.0f);
glTexCoord2f(0.0f, 1.0f); 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(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f, 1.0f);
glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f, 1.0f, 1.0f);
glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f, 1.0f, -1.0f);
glEnd();
glFlush();
glDisable(GL_TEXTURE_2D);
}
void resizeWindow(int x, int y)
{
if (y == 0 || x == 0) return;
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(40.0,(GLdouble)x/(GLdouble)y,0.5,20.0);
glMatrixMode(GL_MODELVIEW);
glViewport(0,0,x,y);
}
void specialKeys( int key, int x, int y ) {
if (key == GLUT_KEY_RIGHT)
rotate_y += 5;
else if (key == GLUT_KEY_LEFT)
rotate_y -= 5;
else if (key == GLUT_KEY_UP)
rotate_x += 5;
else if (key == GLUT_KEY_DOWN)
rotate_x -= 5;
glutPostRedisplay();
}
char* filename = "./salt_on_spoon.bmp";
int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB | GLUT_DEPTH);
glutInitWindowSize(240, 240);
glutInitWindowPosition(100, 100);
glutCreateWindow(argv[0]);
loadTextureFromFile( filename );
glutDisplayFunc(drawScene);
glutSpecialFunc(specialKeys);
glutReshapeFunc(resizeWindow);
glutMainLoop();
return 0;
}
Your callback is modifying rotate_x and rotate_y, but you're using different variables for the rotations:
glRotatef(yRotated, 0, 1, 0);
glRotatef(zRotated, 0, 0, 1);
Try this:
#include <GL/glut.h>
GLfloat pos_x = 0, pos_y = 0;
void specialKeys( int key, int x, int y )
{
const float step = 0.01;
if (key == GLUT_KEY_RIGHT)
pos_x += step;
else if (key == GLUT_KEY_LEFT)
pos_x -= step;
else if (key == GLUT_KEY_UP)
pos_y += step;
else if (key == GLUT_KEY_DOWN)
pos_y -= step;
glutPostRedisplay();
}
void drawScene(void)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
double x = glutGet( GLUT_WINDOW_WIDTH );
double y = glutGet( GLUT_WINDOW_HEIGHT );
gluPerspective(40.0,x/y,0.5,20.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslatef(0.0,0.0,-5);
glTranslatef( pos_x, pos_y, 0 );
glBegin(GL_QUADS);
// Front Face
// Back Face
glColor3ub(255,0,0);
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);
// Top Face
// Bottom Face
glColor3ub(0,255,0);
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
glColor3ub(0,0,255);
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
glColor3ub(255,255,255);
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();
glFlush();
}
int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB | GLUT_DEPTH);
glutInitWindowSize(240, 240);
glutInitWindowPosition(100, 100);
glutCreateWindow(argv[0]);
glutDisplayFunc(drawScene);
glutSpecialFunc(specialKeys);
glutMainLoop();
return 0;
}
So I have 2 cubes in a display list and I want one of them be pickable so I can maybe change his color or something like that.
When I click on a cube then the screen turns black and nothing happens, the console gives me output of the closest hit but the screen turns black and doesn't show anything.
Here is my cpp file:
#include "glwidget.h"
#include <QDomDocument>
#include <QDebug>
#include <QFile>
#include <math.h>
#include <QString>
#include <stdlib.h>
GLWidget::GLWidget(QWidget *parent):QGLWidget(parent)
{
camPosx = 0.0, camPosy = 0.0, camPosz = 1.0;
camViewx = 0.0, camViewy = 0.0, camViewz = 0.0;
camUpx = 0.0, camUpy = 1.0, camUpz = 0.0;
camAngle = 0.0;
camViewz = -cos(camAngle);
camViewx = sin(camAngle);
mode = 1;
timer = new QTimer();
connect( timer, SIGNAL(timeout()), this, SLOT(updateGL()) );
}
void GLWidget::initializeGL() {
loadGLTextures();
glEnable(GL_TEXTURE_2D); // Enable Texture Mapping
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_LIGHT0); // Quick And Dirty Lighting (Assumes Light0 Is Set Up)
glEnable(GL_LIGHTING); // Enable Lighting
glEnable(GL_COLOR_MATERIAL); // Enable Material Coloring
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); // Perspective Calculations
buildLists(2); // Creating displaylist #
glLoadIdentity();
timer->start(50);
}
void GLWidget::resizeGL(int width, int height) {
//set viewport
glViewport(0,0,width,height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
//set persepective
//change the next line order to have a different perspective
aspect_ratio=(GLdouble)width/(GLdouble)height;
gluPerspective(45.0f, aspect_ratio, 0.1 , 100.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
void GLWidget::paintGL() {
glEnable(GL_DEPTH_TEST);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
// store current matrix
glMatrixMode( GL_MODELVIEW );
glPushMatrix( );
gluLookAt(camPosx ,camPosy ,camPosz,
camPosx + camViewx,camViewy,camPosz + camViewz,
camUpx, camUpy, camUpz );
if (mode == 2) {
startPicking();
}
glColor3f(1.0f,0.0f,0.0f);
glCallList(displayList[0]);
glTranslatef(5.0,0.0,0.0);
glColor3f(0.0f,1.0f,1.0f);
glCallList(displayList[0]);
if (mode == 2)
stopPicking();
// glEnable( GL_LIGHTING );
// glEnable( GL_LIGHT0 );
// glScalef(10.0,10.0,10.0);
// glBindTexture(GL_TEXTURE_2D, texture[0]);
// glBegin(GL_QUADS);
// // Front Face
// glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, -1.0f, 1.0f); // Bottom Left Of The Texture and Quad
// glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, -1.0f, 1.0f); // Bottom Right Of The Texture and Quad
// glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f, 1.0f, 1.0f); // Top Right Of The Texture and Quad
// glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f, 1.0f, 1.0f); // Top Left Of The Texture and Quad
// // Back Face
// glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f, -1.0f); // Bottom Right Of The Texture and Quad
// glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f, 1.0f, -1.0f); // Top Right Of The Texture and Quad
// glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f, 1.0f, -1.0f); // Top Left Of The Texture and Quad
// glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f, -1.0f); // Bottom Left Of The Texture and Quad
// // Top Face
// glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f, 1.0f, -1.0f); // Top Left Of The Texture and Quad
// glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, 1.0f, 1.0f); // Bottom Left Of The Texture and Quad
// glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, 1.0f, 1.0f); // Bottom Right Of The Texture and Quad
// glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f, 1.0f, -1.0f); // Top Right Of The Texture and Quad
// // Bottom Face
// glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f, -1.0f, -1.0f); // Top Right Of The Texture and Quad
// glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f, -1.0f, -1.0f); // Top Left Of The Texture and Quad
// glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f, 1.0f); // Bottom Left Of The Texture and Quad
// glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f, 1.0f); // Bottom Right Of The Texture and Quad
// // Right face
// glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, -1.0f, -1.0f); // Bottom Right Of The Texture and Quad
// glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f, 1.0f, -1.0f); // Top Right Of The Texture and Quad
// glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f, 1.0f, 1.0f); // Top Left Of The Texture and Quad
// glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f, 1.0f); // Bottom Left Of The Texture and Quad
// // Left Face
// glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, -1.0f, -1.0f); // Bottom Left Of The Texture and Quad
// glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f, 1.0f); // Bottom Right Of The Texture and Quad
// glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f, 1.0f, 1.0f); // Top Right Of The Texture and Quad
// glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f, 1.0f, -1.0f); // Top Left Of The Texture and Quad
// glEnd();
// // XML
// QDomDocument doc( "AdBookML" );
// QDomNode n;
// QDomElement e;
// QFile file( "test2.xml" );
// QString s;
// QStringList sl;
//// if( !file.open(QIODevice::ReadOnly))
//// qDebug("probleem bij het openen");
// if( !doc.setContent( &file ) )
// {
// file.close();
// }
// file.close();
// QDomElement root = doc.documentElement();
// if( root.tagName() != "playlist" )
// // qDebug("root is different");
// //qDebug( root.tagName() );
// // doorheen u boom lopen
// n = root;
// float f1, f2, f3;
// glDisable( GL_LIGHTING );
// glBegin(GL_TRIANGLES);
// for(int i = 0; i< n.childNodes().length(); i++) // voor alle triangles
// {
// if(n.childNodes().at(i).toElement().tagName() == "triangle")
// {
// for(int j =0; j < 4; j++) // voor alle punten
// {
// e = n.childNodes().at(i).childNodes().at(j).toElement(); // e is een punt
// //qDebug(e.tagName());
// s = e.text();
// sl = s.split(" "); // opsplitsen naar het x, y , z coordinaat;
// f1 = sl.at(0).toFloat();
// f2 = sl.at(1).toFloat();
// f3 = sl.at(2).toFloat();
// if( j > 0)
// glVertex3f(f1, f2, f3); // de vertex tekenen
// if(j == 0)
// glColor3f(f1,f2,f3);
// }
// }
// }
// glEnd();
// glEnable(GL_LIGHTING);
// restore current matrix
glMatrixMode( GL_MODELVIEW );
glPopMatrix( );
}
void GLWidget::loadGLTextures()
{
QImage t;
QImage b;
if ( !b.load( "images/redbrick.png" ) )
{
qDebug("Didn't found the image.");
b = QImage( 16, 16, QImage::Format_RGB32 );
b.fill( 1 );
}
t = QGLWidget::convertToGLFormat( b );
glGenTextures( 1, &texture[0] );
glBindTexture( GL_TEXTURE_2D, texture[0] );
glTexImage2D( GL_TEXTURE_2D, 0, 3, t.width(), t.height(), 0, GL_RGBA, GL_UNSIGNED_BYTE, t.bits() );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
}
//Functie die display lists kan aanmaken, het aantal ( is het aantal displaylists )
GLvoid GLWidget::buildLists(int aantal)
{
displayList = new GLuint[aantal];
for(int i = 0; i < aantal; i++)
{
displayList[i]=glGenLists(aantal); // Maak x Aantal displaylists
glNewList(displayList[i],GL_COMPILE); //start met de eerste display list te compile
//Hieronder moet er xml worden ingeladen
glBegin(GL_QUADS);
// Bottom Face
glNormal3f( 0.0f,-1.0f, 0.0f);
glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f, -1.0f, -1.0f);
glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f, -1.0f, -1.0f);
glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f, 1.0f);
glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f, 1.0f);
// Front Face
glNormal3f( 0.0f, 0.0f, 1.0f);
glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, -1.0f, 1.0f);
glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, -1.0f, 1.0f);
glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f, 1.0f, 1.0f);
glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f, 1.0f, 1.0f);
// Back Face
glNormal3f( 0.0f, 0.0f,-1.0f);
glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f, -1.0f);
glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f, 1.0f, -1.0f);
glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f, 1.0f, -1.0f);
glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f, -1.0f);
// Right face
glNormal3f( 1.0f, 0.0f, 0.0f);
glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, -1.0f, -1.0f);
glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f, 1.0f, -1.0f);
glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f, 1.0f, 1.0f);
glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f, 1.0f);
// Left Face
glNormal3f(-1.0f, 0.0f, 0.0f);
glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, -1.0f, -1.0f);
glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f, 1.0f);
glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f, 1.0f, 1.0f);
glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f, 1.0f, -1.0f);
glEnd();
glEndList();
}
}
//functie die zorgt dat we renderen in selectiemode
void GLWidget::renderInSelectionMode() {
glInitNames(); //Creates empty stack
glPushName(1); //Push a name on the stack
//draw something
glColor3f(1.0f,0.0f,0.0f);
glCallList(displayList[0]);
glPopName(); //pop a name from the stack
glPushName(2); //Push a name on the stack
//draw something
glTranslatef(5.0,0.0,0.0);
glColor3f(0.0f,1.0f,1.0f);
glCallList(displayList[0]);
glPopName(); //Pops a name from the stack
}
void GLWidget::startPicking() {
GLint viewport[4];
glSelectBuffer(BUFSIZE,selectBuf);
glRenderMode(GL_SELECT);
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();
glGetIntegerv(GL_VIEWPORT,viewport);
gluPickMatrix(cursorX,viewport[3]-cursorY,5,5,viewport);
gluPerspective(45,aspect_ratio,0.1,1000);
glMatrixMode(GL_MODELVIEW);
glInitNames();
}
void GLWidget::stopPicking() {
int hits;
// restoring the original projection matrix
glMatrixMode(GL_PROJECTION);
glPopMatrix();
glMatrixMode(GL_MODELVIEW);
glFlush();
// returning to normal rendering mode
hits = glRenderMode(GL_RENDER);
// if there are hits process them
if (hits != 0)
processHits(hits,selectBuf);
}
void GLWidget::processHits (GLint hits, GLuint buffer[])
{
unsigned int i, j;
GLuint names, *ptr, minZ,*ptrNames, numberOfNames;
printf ("hits = %d\n", hits);
ptr = (GLuint *) buffer;
minZ = 0xffffffff;
for (i = 0; i < hits; i++) {
names = *ptr;
ptr++;
if (*ptr < minZ) {
numberOfNames = names;
minZ = *ptr;
ptrNames = ptr+2;
}
ptr += names+2;
}
printf ("The closest hit names are ");
ptr = ptrNames;
for (j = 0; j < numberOfNames; j++,ptr++) {
printf ("%d ", *ptr);
}
printf ("\n");
}
void GLWidget::mousePressEvent(QMouseEvent * e)
{
if(e->button() == Qt::LeftButton)
{
qDebug("mouse");
qDebug("%d",QCursor::pos().x());
this->cursorX = QCursor::pos().x();
this->cursorY = QCursor::pos().y();
this->mode = 2;
}
}
void GLWidget::keyPressEvent( QKeyEvent * e ) {
double fraction = 0.1f;
if(e->key() == Qt::Key_Up)
{
camPosz += camViewz * fraction;
camPosx += camViewx * fraction ;
}
if(e->key() == Qt::Key_Down)
{
camPosz -= camViewz * fraction;
camPosx -= camViewx * fraction ;
}
if(e->key() == Qt::Key_Left)
{
camAngle -= 0.05f;
camViewz = -cos(camAngle);
camViewx = sin(camAngle);
}
if(e->key() == Qt::Key_Right)
{
qDebug("cam angle is %f", camAngle);
camAngle +=0.05f;
camViewz = -cos(camAngle);
camViewx = sin(camAngle);
}
}
#ifndef GLWIDGET_H
#define GLWIDGET_H
#include <QtOpenGL/QGLWidget>
#include <gl/GLU.h>
#include <QImage>
#include <QKeyEvent>
#include <QMouseEvent>
#include <QTimer>
#define BUFSIZE 512
class GLWidget: public QGLWidget
{
Q_OBJECT
public:
GLWidget(QWidget *parent = NULL);
private:
double camPosx,camPosy,camPosz;
double camUpx,camUpy,camUpz;
double camViewx,camViewy,camViewz;
double camAngle;
protected:
void initializeGL();
void resizeGL(int width, int height);
void paintGL();
void keyPressEvent(QKeyEvent * e);
void mousePressEvent(QMouseEvent * e);
QTimer* timer;
void loadGLTextures();
GLuint texture[1];
GLuint * displayList;
void renderInSelectionMode();
GLvoid buildLists(int aantal);
void startPicking();
void stopPicking();
void processHits (GLint hits, GLuint buffer[]);
GLuint selectBuf[BUFSIZE];
GLdouble aspect_ratio;
int cursorY;
int cursorX;
int mode;
};
#endif // GLWIDGET_H
this is the normal view without clicking once
http://imageshack.us/photo/my-images/233/31536776.png/
then when clicked it keeps getting in startpicking and stop picking and gives a black screen
http://imageshack.us/photo/my-images/13/14180995.png/
and then after closing the window so it stops running it gives me this output http://imageshack.us/photo/my-images/861/13486229.png/
Could be wrong, but it looks like you aren't resetting your mode-variable back to 1 after the first mouseclick anywhere, so the start- & stopPicking-methods are called on each frame from the first click onwards. If that's not the case, then you probably have some problem with gl-states/matrices not all being reset correctly after the picking.
I'm trying to map the input from my webcam to a plane in OpenGL. I'm using OpenCV to get the images from the webcam.
The problem I have is that the texture is vertically inverted, if my texture is "v", the current result is "^".
I want to fit the image taken from the webcam to my plane (2x2). Its lower left corner is -1, -1 and the upper right corner is 1,1.
The code is:
const int VIEWPORT_WIDTH = 640;
const int VIEWPORT_HEIGHT = 480;
const int KEY_ESCAPE = 27;
CvCapture* g_Capture;
IplImage* image;
GLint g_hWindow;
GLvoid InitGL();
GLvoid OnDisplay();
GLvoid OnReshape(GLint w, GLint h);
GLvoid OnKeyPress (unsigned char key, GLint x, GLint y);
int main(int argc, char* argv[])
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH);
glutInitWindowPosition(100, 100);
glutInitWindowSize(VIEWPORT_WIDTH, VIEWPORT_HEIGHT);
g_hWindow = glutCreateWindow("Image");
image = cvLoadImage("average.jpg", 1);
gluBuild2DMipmaps(GL_TEXTURE_2D, GL_RGB, image->width, image->height, GL_RGB, GL_UNSIGNED_BYTE, image->imageData);
InitGL();
glutMainLoop();
return 0;
}
GLvoid InitGL()
{
glClearColor (0.0, 0.0, 0.0, 0.0);
glutDisplayFunc(OnDisplay);
glutReshapeFunc(OnReshape);
glutKeyboardFunc(OnKeyPress);
}
GLvoid OnDisplay(void)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glEnable(GL_TEXTURE_2D);
glPushMatrix();
glTranslatef(0.0f, 0.0f, -2.5f);
glBegin(GL_QUADS);
glTexCoord2f(0.0f, 0.0f);
glVertex3f(-1.0f,-1.0f, 1.0f);
glTexCoord2f(1.0f, 0.0f);
glVertex3f( 1.0f,-1.0f, 1.0f);
glTexCoord2f(1.0f, 1.0f);
glVertex3f( 1.0f, 1.0f, 1.0f);
glTexCoord2f(0.0f, 1.0f);
glVertex3f(-1.0f, 1.0f, 1.0f);
glEnd();
glPopMatrix();
glutSwapBuffers();
}
GLvoid OnReshape(GLint width, GLint height)
{
if (height==0)
height=1;
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glViewport(0, 0, width, height);
gluPerspective(45.0f,(GLfloat)width/(GLfloat)height, 1.0f, 10.0f);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt( 0.0, 0.0, 0.0, 0.0, 0.0, -6.0, 0.0f, 1.0f, 0.0f);
}
GLvoid OnKeyPress(unsigned char key, int x, int y)
{
switch (key) {
case KEY_ESCAPE:
cvReleaseImage(&image);
glutDestroyWindow(g_hWindow);
exit(0);
break;
}
glutPostRedisplay();
}
BTW. In this code I'm loading an image instead of getting from the webcam.
Any suggestion?
Flip the texture coordinates on the quad you're rendering. OpenGL does store texture "upside-down" from how most people assume they'd be, so the simplest way to handle it is just work with OGL.
glTexCoord2f(0.0f, 1.0f);
glVertex3f(-1.0f,-1.0f, 1.0f);
glTexCoord2f(1.0f, 1.0f);
glVertex3f( 1.0f,-1.0f, 1.0f);
glTexCoord2f(1.0f, 0.0f);
glVertex3f( 1.0f, 1.0f, 1.0f);
glTexCoord2f(0.0f, 0.0f);
glVertex3f(-1.0f, 1.0f, 1.0f);
should do it, I think.