I am struggling with loading src/up.bmp and showing it in 2D overlaid on my 3D environment.
But nothing does appear. Where is my mistake?
#define SDL_MAIN_HANDLED
#include <math.h>
#include <SDL.h>
#include <iostream>
#include <GL/freeglut.h>
using namespace std;
int w_width = 800;
int w_height = 500;
string w_title = "Model viewer";
float line_width = 2.0f;
float camera_radius = 100.0f;
float axis_size = 20.0;
SDL_Surface* button1;
GLuint TextureID;
void draw_button(SDL_Surface* button)
{
glGenTextures(1, &TextureID);
glBindTexture(GL_TEXTURE_2D, TextureID);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
gluBuild2DMipmaps(GL_TEXTURE_2D, 3, button->w, button->h, GL_RGB, GL_UNSIGNED_BYTE, button->pixels);
}
void display()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
const float ratio = (float)glutGet(GLUT_SCREEN_WIDTH) / (float)glutGet(GLUT_SCREEN_HEIGHT);
static double t = 0.0;
const float deg2rad = 3.1415926f / 180.0f;
float cam_x = camera_radius*float(cos(20.0f*deg2rad))*float(cos(0.5235*deg2rad));
float cam_y = camera_radius*float(sin(20.f*deg2rad))*float(cos(0.5235*deg2rad));
float cam_z = camera_radius*float(sin(0.5235*deg2rad));
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(90, ratio, 0.01, 10000);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(cam_x, cam_y, cam_z, 0, 0, 0, 0, 0, 1);
// sphere
glPushMatrix();
glColor3ub(255, 0, 0);
glTranslated(
0,
0,
0);
glutSolidSphere(1, 20, 20);
glPopMatrix();
draw_button(button1);
glFlush();
glutSwapBuffers();
}
void timer_event(int value)
{
glutPostRedisplay();
glutTimerFunc(100, timer_event, value);
}
int main(int argc, char *argv[])
{
glutInit(&argc, argv);
glutSetOption(GLUT_MULTISAMPLE, 8);
glutInitDisplayMode(GLUT_RGBA | GLUT_DEPTH | GLUT_DOUBLE | GLUT_MULTISAMPLE);
glutTimerFunc(30, timer_event, 1);
glutInitWindowSize(w_width, w_height);
glutInitWindowPosition(10, 10);
glutCreateWindow(argv[0]);
glutSetWindowTitle(w_title.c_str());
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_BLEND);
glutDisplayFunc(display);
glutSetOption(GLUT_ACTION_ON_WINDOW_CLOSE,
GLUT_ACTION_GLUTMAINLOOP_RETURNS);
glEnable(GL_COLOR_MATERIAL);
glEnable(GL_TEXTURE_2D);
button1 = SDL_LoadBMP("src/up.bmp");
if (button1 == NULL)
{
cout << "Image not found" << endl;
exit(1);
}
glutMainLoop();
SDL_FreeSurface(button1);
return 0;
}
Here is a minimal example I can come up with:
#define SDL_MAIN_HANDLED
#include <math.h>
#include <SDL.h>
#include <iostream>
#include <GL/gl.h>
#include <GL/freeglut.h>
using namespace std;
int w_width = 800;
int w_height = 500;
string w_title = "Model viewer";
float line_width = 2.0f;
float camera_radius = 100.0f;
float axis_size = 20.0;
SDL_Surface* button1;
GLuint TextureID;
static void prepare_texture(SDL_Surface *button)
{
glGenTextures(1, &TextureID);
glBindTexture(GL_TEXTURE_2D, TextureID);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
// convert surface to RGB8
SDL_Surface *rgb = SDL_CreateRGBSurface(0, button->w, button->h, 24, 0xff, 0xff00, 0xff0000, 0);
SDL_BlitSurface(button, NULL, rgb, NULL);
gluBuild2DMipmaps(GL_TEXTURE_2D, 3, button->w, button->h, GL_RGB, GL_UNSIGNED_BYTE, rgb->pixels);
SDL_FreeSurface(rgb);
}
static void draw_button()
{
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
glBindTexture(GL_TEXTURE_2D, TextureID);
glBegin(GL_QUADS);
glTexCoord2f(0.0f, 1.0f);
glVertex2f(0.1f, 0.1f);
glTexCoord2f(0.0f, 0.0f);
glVertex2f(0.1f, 0.2f);
glTexCoord2f(1.0f, 0.0f);
glVertex2f(0.2f, 0.2f);
glTexCoord2f(1.0f, 1.0f);
glVertex2f(0.2f, 0.1f);
glEnd();
}
void display()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
const float ratio = (float)glutGet(GLUT_SCREEN_WIDTH) / (float)glutGet(GLUT_SCREEN_HEIGHT);
static double t = 0.0;
const float deg2rad = 3.1415926f / 180.0f;
float cam_x = camera_radius*float(cos(20.0f*deg2rad))*float(cos(0.5235*deg2rad));
float cam_y = camera_radius*float(sin(20.f*deg2rad))*float(cos(0.5235*deg2rad));
float cam_z = camera_radius*float(sin(0.5235*deg2rad));
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(90, ratio, 0.01, 10000);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(cam_x, cam_y, cam_z, 0, 0, 0, 0, 0, 1);
// sphere
glPushMatrix();
glColor3ub(255, 0, 0);
glTranslated(
0,
0,
0);
glutSolidSphere(1, 20, 20);
glPopMatrix();
draw_button();
glFlush();
glutSwapBuffers();
}
void timer_event(int value)
{
glutPostRedisplay();
glutTimerFunc(100, timer_event, value);
}
int main(int argc, char *argv[])
{
glutInit(&argc, argv);
glutSetOption(GLUT_MULTISAMPLE, 8);
glutInitDisplayMode(GLUT_RGBA | GLUT_DEPTH | GLUT_DOUBLE | GLUT_MULTISAMPLE);
glutTimerFunc(30, timer_event, 1);
glutInitWindowSize(w_width, w_height);
glutInitWindowPosition(10, 10);
glutCreateWindow(argv[0]);
glutSetWindowTitle(w_title.c_str());
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_BLEND);
glutDisplayFunc(display);
glutSetOption(GLUT_ACTION_ON_WINDOW_CLOSE,
GLUT_ACTION_GLUTMAINLOOP_RETURNS);
glEnable(GL_COLOR_MATERIAL);
glEnable(GL_TEXTURE_2D);
button1 = SDL_LoadBMP("up.bmp");
if (button1 == NULL)
{
cout << "Image not found" << endl;
exit(1);
}
prepare_texture(button1);
SDL_FreeSurface(button1);
glutMainLoop();
return 0;
}
Note identity projection, which maps screen to [-1,1] range; you may want something more like gluOrtho2D.
Related
I'm trying to make a 3D shooter. I think the image is loading because its dimensions are displayed, but it is not displayed as a texture. The program compiles and runs without errors but no texture. I do not know where I am making a mistake.
main.cpp:
#include "Functions.h"
int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
glutInitWindowSize(wnd_width, wnd_height);
glutInitWindowPosition(300, 100);
glEnable(GL_DEPTH_TEST);
glEnable(GL_NORMALIZE);
glutCreateWindow("OpenGL my");
glutDisplayFunc(display);
glutIdleFunc(Idle);
glutSpecialFunc(KeyPressed);
TextureInit();
glutMainLoop();
return 0;
}
functions.h
#define STB_IMAGE_IMPLEMENTATION
#include <GL/glut.h>
#include <stb_image.h>
#include <iostream>
#include "point.h"
#include "camera.h"
int wnd_width=1300;
int wnd_height=900;
GLdouble aspect = wnd_width/wnd_height;
Camera cam;
unsigned int texture;
float text_coords[] = {0,0, 1,0, 1,1, 0,1};
void DrawFloor();
void DrawWall(float x, float width, float height);
void KeyPressed(int key, int x, int y);
void TextureInit();
void display();
void Idle();
void display(){
glClearColor(0.6, 0.8, 1, 1);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(90, aspect, 0.1, 3);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(cam.pos.x, cam.pos.y, cam.pos.z,
cam.view.x, cam.view.y, cam.view.z,
0, 0.5, 0);
glBegin(GL_QUADS);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, texture);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glTexCoordPointer(2, GL_FLOAT, 0, text_coords);
//glColor3f(0, 0, 0.7);
DrawFloor();
//glColor3f(0, 0.8, 0.1);
DrawWall(-0.5, 2, 0.7);
DrawWall(0.5, 2, 0.7);
glEnd();
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glutSwapBuffers();
}
void Idle(){
}
void DrawFloor(){
glVertex3d(1, 0, 2.5);
glVertex3d(1, 0, 0);
glVertex3d(-1, 0, 0);
glVertex3d(-1, 0, 2.5);
}
void DrawWall(float x, float width, float height){
glVertex3f(x, height, 0);
glVertex3f(x, height, width);
glVertex3f(x, 0, width);
glVertex3f(x, 0, 0);
}
void KeyPressed(int key, int x, int y){
switch (key) {
case GLUT_KEY_UP: { cam.MoveForward(); break; }
case GLUT_KEY_DOWN: { cam.MoveBack(); break; }
case GLUT_KEY_LEFT: {cam.TurnLeft(); break; }
case GLUT_KEY_RIGHT: {cam.TurnRight(); break; }
}
cam.PrintPosition();
glutPostRedisplay();
}
void TextureInit(){
int width, height, cnt;
unsigned char* data = stbi_load("whitemarble.jpg", &width, &height, &cnt, 0);
if(data==nullptr) std::cout<< "NO\n";
else std::cout<<width<<'\t'<<height<<'\n';
glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_2D, texture);
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_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height,
0, GL_RGB, GL_UNSIGNED_BYTE, data);
glBindTexture(GL_TEXTURE_2D, 0);
stbi_image_free(data);
}
redone. Now it works. Thanks. But the picture is very stretched.
#define STB_IMAGE_IMPLEMENTATION
#include <GL/glut.h>
#include <stb_image.h>
#include <iostream>
#include "point.h"
#include "camera.h"
int wnd_width=1300;
int wnd_height=900;
GLdouble aspect = wnd_width/wnd_height;
Camera cam;
unsigned int texture;
float text_coords[] = {0,0, 1,0, 1,1, 0,1};
void DrawFloor();
void DrawWall(float x, float width, float height);
void KeyPressed(int key, int x, int y);
void TextureInit();
void display();
void Idle();
void TextureInit(){
int width, height, cnt;
unsigned char* data = stbi_load("whitemarble.jpg", &width, &height, &cnt, 0);
if(data==nullptr) std::cout<< "NO\n";
else std::cout<<width<<'\t'<<height<<'\n';
glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_2D, texture);
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_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height,
0, GL_RGBA, GL_UNSIGNED_BYTE, data);
glBindTexture(GL_TEXTURE_2D, 0);
stbi_image_free(data);
}
void display(){
glClearColor(0.6, 0.8, 1, 1);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(90, aspect, 0.1, 3);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(cam.pos.x, cam.pos.y, cam.pos.z,
cam.view.x, cam.view.y, cam.view.z,
0, 0.5, 0);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, texture);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glBegin(GL_QUADS);
DrawFloor();
DrawWall(-0.5, 2, 0.7);
DrawWall(0.5, 2, 0.7);
glEnd();
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glutSwapBuffers();
}
void DrawFloor(){
glTexCoord2d(0, 0);
glVertex3d(1, 0, 2.5);
glTexCoord2d(1, 0);
glVertex3d(1, 0, 0);
glTexCoord2d(1, 1);
glVertex3d(-1, 0, 0);
glTexCoord2d(0, 1);
glVertex3d(-1, 0, 2.5);
}
void DrawWall(float x, float width, float height){
glVertex3f(x, height, 0);
glVertex3f(x, height, width);
glVertex3f(x, 0, width);
glVertex3f(x, 0, 0);
}
void KeyPressed(int key, int x, int y){
switch (key) {
case GLUT_KEY_UP: { cam.MoveForward(); break; }
case GLUT_KEY_DOWN: { cam.MoveBack(); break; }
case GLUT_KEY_LEFT: {cam.TurnLeft(); break; }
case GLUT_KEY_RIGHT: {cam.TurnRight(); break; }
}
cam.PrintPosition();
glutPostRedisplay();
}
void Idle(){
}```
Your code is causing several Only a subset of GL commands can be used between glBegin and glEnd. You have to call glBegin immediately before specifying the vertices:
void display(){
glClearColor(0.6, 0.8, 1, 1);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(90, aspect, 0.1, 3);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(cam.pos.x, cam.pos.y, cam.pos.z,
cam.view.x, cam.view.y, cam.view.z,
0, 0.5, 0);
// glBegin(GL_QUADS); // <--- DELETE
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, texture);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glTexCoordPointer(2, GL_FLOAT, 0, text_coords);
glBegin(GL_QUADS); // <--- INSERT
//glColor3f(0, 0, 0.7);
DrawFloor();
//glColor3f(0, 0.8, 0.1);
DrawWall(-0.5, 2, 0.7);
DrawWall(0.5, 2, 0.7);
glEnd();
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glutSwapBuffers();
}
You cannot mix fix function attributes and glBegin/glEnd sequences. Use glTexCoord instead:
glTexCoord2d(0, 0);
glVertex3d(1, 0, 2.5);
glTexCoord2d(1, 0);
glVertex3d(1, 0, 0);
glTexCoord2d(1, 1);
glVertex3d(-1, 0, 0);
glTexCoord2d(0, 1);
glVertex3d(-1, 0, 2.5);
I have created a rotating wired sphere. I have done textures to a cube but sphere seems to be a problem.
I want to add world map as a texture to this sphere. Any suggestions?
#include <iostream>
#include <stdlib.h>
#include <GL/glut.h>
#include <thread>
#include <chrono>
#define STB_IMAGE_IMPLEMENTATION
#include "stb_image.h"
using namespace std;
GLuint texture;
int start = 1;
GLfloat xRotated, yRotated, zRotated;
GLdouble radius = 1;
void init() {
glOrtho(-1000 / 2, 1000 / 2, -1000 / 2, 1000 / 2, -500, 500);
}
GLuint glInitTexture(char* filename)
{
GLuint t = 0;
int width, height, nrChannels;
stbi_set_flip_vertically_on_load(true);
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
unsigned char* data = stbi_load(filename, &width, &height, &nrChannels, 0);
glGenTextures(1, &t);
glBindTexture(GL_TEXTURE_2D, t);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
//unsigned char data[] = { 255, 0, 0, 255 };
if (data)
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, data);
else
std::cout << "fail";
return t;
}
void drawImage(GLuint file, float x, float y, float w, float h)
{
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
glPushMatrix();
//glTranslatef(x, y, 0.0);
//glRotatef(angle, 0.0, 0.0, 1.0);
//glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
glBindTexture(GL_TEXTURE_2D, file);
glEnable(GL_TEXTURE_2D);
glClear(GL_COLOR_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslatef(0.0, 0.0, -4.5);
glRotatef(yRotated, 0.0, 1.0, 0.0);
glEnable(GL_TEXTURE_2D);
GLUquadric *qobj = gluNewQuadric();
gluQuadricTexture(qobj, GL_TRUE);
gluSphere(qobj, radius, 20, 20);
gluDeleteQuadric(qobj);
glDisable(GL_TEXTURE_2D);
glFlush();
yRotated += 0.01;
//glBindTexture(GL_TEXTURE_2D, 0);
glFlush();
glPopMatrix();
glDisable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, 0);
}
//Plots points of both graphs together
//Displays map on screen
void drawMap() {
std::cout << "\nDraw map\n";
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
const double w = glutGet(GLUT_WINDOW_WIDTH);
const double h = glutGet(GLUT_WINDOW_HEIGHT);
gluPerspective(90.0, w / h, 0.1, 1000.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslatef(0, 0, -15);
for (int i = 0; i < 10000; i++) {
glClear(GL_DEPTH_BUFFER_BIT);
drawImage(texture, 0, 0, 100, 200);
//std::this_thread::sleep_for(std::chrono::milliseconds(500));
}
glutSwapBuffers();
glEnd();
glFlush();
}
void render()
{
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glEnable(GL_DEPTH_TEST);
//glFlush();
glPointSize(5);
glColor3f(1, 1, 1);
glBegin(GL_LINES);
glVertex3f(-450, -450, 10);
glVertex3f(-450, -250, 10);
glEnd();
glBegin(GL_LINES);
glVertex3f(-450, -450, 10);
glVertex3f(-250, -450, 10);
glEnd();
drawMap();
//plotPoints();
glFlush();
}
void Kbevent(unsigned char key, int x, int y) {
if (key == 's') {
start = start % 2;
glutPostRedisplay();
}
}
int main(int argc, char* argv[])
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB | GLUT_DEPTH);
glutInitWindowSize(1560, 810);
glutCreateWindow("Applying Textures");
init();
xRotated = yRotated = zRotated = 30.0;
xRotated = 33;
yRotated = 40;
char fn[] = "map.jpg";
texture = glInitTexture(fn);
glutDisplayFunc(render);
//glutReshapeFunc(reshapeFunc);
//glutIdleFunc(idleFunc);
glutKeyboardFunc(Kbevent);
glutMainLoop();
return 0;
}
The problem with applying a 2D texture is that when you wrap a 2D texture onto a sphere, the top and bottom area of the sphere, the texture looks squeezed.
I suggest to use gluSphere and gluQuadricTexture rather than glutSolidSphere. e.g:
glEnable(GL_TEXTURE_2D);
GLUquadric *qobj = gluNewQuadric();
gluQuadricTexture(qobj, GL_TRUE);
gluSphere(qobj, radius, 20, 20);
gluDeleteQuadric(qobj);
glDisable(GL_TEXTURE_2D);
For an continuously rotation, you have increment the rotation angle and to continuously update the window (glutPostRedisplay). e.g.:
void redisplayFunc(void)
{
glClear(GL_COLOR_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslatef(0.0, 0.0, -4.5);
glRotatef(yRotated, 0.0, 1.0, 0.0);
glEnable(GL_TEXTURE_2D);
GLUquadric *qobj = gluNewQuadric();
gluQuadricTexture(qobj, GL_TRUE);
gluSphere(qobj, radius, 20, 20);
gluDeleteQuadric(qobj);
glDisable(GL_TEXTURE_2D);
glFlush();
yRotated += 1;
glutPostRedisplay();
}
I started with opengl texturing and everything was working well. Now I am trying to load a bmp and make white part transparent using glEnable(GL_BLEND); and glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
This is my source code:
float kSpeedForw=0.0f;
GLuint texture[1];
CCamera g_Camera;
GLfloat xrot = 0;
GLfloat yrot = 0;
GLfloat zrot = 0;
bool g_bFullScreen = true;
HWND g_hWnd;
RECT g_rRect;
HDC g_hDC;
HGLRC g_hRC;
HINSTANCE g_hInstance;
float jump = -0.1;
GLfloat LightAmbient[] = { 0.5f, 0.5f, 0.5f, 1.0f };
GLfloat LightDiffuse[] = { 1.0f, 1.0f, 1.0f, 1.0f };
GLfloat LightPosition[] = { 0.0f, 0.0f, 2.0f, 1.0f };
void Init(HWND hWnd)
{
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
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); // Really Nice Perspective Calculations
glLightfv(GL_LIGHT1, GL_AMBIENT, LightAmbient); // Setup The Ambient Light
glLightfv(GL_LIGHT1, GL_DIFFUSE, LightDiffuse); // Setup The Diffuse Light
glLightfv(GL_LIGHT1, GL_POSITION, LightPosition); // Position The Light
glEnable(GL_LIGHT1); // Enable Light One
glColor4f(1.0f, 1.0f, 1.0f, 0.5); // Full Brightness. 50% Alpha
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
g_hWnd = hWnd;
GetClientRect(g_hWnd, &g_rRect);
InitializeOpenGL(g_rRect.right, g_rRect.bottom);
g_Camera.PositionCamera(0, 1.5f, 6, 0, 1.5f, 5, 0, 1, 0);
ShowCursor(false);
}
GLuint LoadTexture(const char * filename)
{
glEnable(GL_TEXTURE_2D);
GLuint texture;
int width, height;
unsigned char * data;
FILE * file;
file = fopen(filename, "rb");
if (file == NULL) return 0;
if (filename=="Data/weed.bmp"){
width = 200;
height = 200;
}
if (filename == "Data/gun.bmp"){
width = 300;
height = 300;
}
data = (unsigned char *)malloc(width * height * 3);
fread(data, width * height * 3, 1, file);
fclose(file);
for (int i = 0; i < width * height; ++i)
{
int index = i * 3;
unsigned char B, R;
B = data[index];
R = data[index + 2];
data[index] = R;
data[index + 2] = B;
}
if (filename == "Data/weed.bmp"){
glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_2D, texture);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
gluBuild2DMipmaps(GL_TEXTURE_2D, 3, width, height, GL_RGB, GL_UNSIGNED_BYTE, data);
free(data);
}
if (filename == "Data/gun.bmp"){
glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_2D, texture);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexImage2D(GL_TEXTURE_2D, 0, 3,width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, data);
}
return texture;
}
WPARAM MainLoop() // main function
{
MSG msg;
Init(g_hWnd);
glClearColor(0, 0, 255, 0);
while (1)
{
if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
if (msg.message == WM_QUIT)
break;
TranslateMessage(&msg);
DispatchMessage(&msg);
}
else if (LockFrameRate(60))
{
g_Camera.SetViewByMouse();
kSpeedForw = 0;
if (jump > -0.1)jump-=0.01;
CheckForMovement();
g_Camera.MoveCamera(kSpeedForw, jump);
RenderScene();
}
}
DeInit();
return(msg.wParam);
}
void RenderScene()
{
glMatrixMode(GL_PROJECTION);
glPopMatrix();
glMatrixMode(GL_MODELVIEW);
glPopMatrix();
glDisable(GL_BLEND);
glEnable(GL_SMOOTH);
glEnable(GL_DEPTH_TEST);
glEnable(GL_TEXTURE_2D);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
gluLookAt(g_Camera.m_vPosition.x, g_Camera.m_vPosition.y, g_Camera.m_vPosition.z,
g_Camera.m_vView.x, g_Camera.m_vView.y, g_Camera.m_vView.z,
g_Camera.m_vUpVector.x, g_Camera.m_vUpVector.y, g_Camera.m_vUpVector.z);
GLuint texture;
texture = LoadTexture("Data/weed.bmp");
glBindTexture(GL_TEXTURE_2D, texture);
glBegin(GL_QUADS);
float i = 0;
glColor3f(1,1,1);
glTexCoord2f(0.0f, 0.0f);
glVertex3f(-10 + i / 5, 0, 10 - i / 5);
glTexCoord2f(50.0f, 0.0f);
glVertex3f(-10 + i / 5, 0, -10 + i / 5);
glTexCoord2f(50.0f, 50.0f);
glVertex3f(10 - i / 5, 0, -10 + i / 5);
glTexCoord2f(0.0f, 50.0f);
glVertex3f(10 - i / 5, 0, 10 - i / 5);
glEnd();
////////////////////////////////////////////////////////////HUD
glDisable(GL_LIGHTING);
glDisable(GL_TEXTURE_2D);
glDisable(GL_DEPTH_TEST);
glDisable(GL_SMOOTH);
glEnable(GL_BLEND); // Turn Blending On
int vPort[4];
glGetIntegerv(GL_VIEWPORT, vPort);
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();
glOrtho(0, vPort[2], 0, vPort[3], -1, 1);
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glLoadIdentity();
GLuint ruka;
ruka = LoadTexture("Data/gun.bmp");
glBindTexture(GL_TEXTURE_2D, ruka);
glBegin(GL_QUADS);
glTexCoord2f(0.0f, 0.0f);
glVertex2f(0, 0);
glTexCoord2f(1.0f, 0.0f);
glVertex2f(450,0);
glTexCoord2f(1.0f, 1.0f);
glVertex2f(450,450);
glTexCoord2f(0.0f, 1.0f);
glVertex2f(0,450);
glEnd();
SwapBuffers(g_hDC);
}
The code works well for loading and rendering the platform(weed.bmp) and it also loads and renders gun fine. But big part of gun.bmp is white. I was hoping to get that part transparent. I was also hoping to add more HUD features, which would also need to be partly transparent.
My gun.bmp file: https://drive.google.com/file/d/0BxxlNcAI0eh9cHZGd1ZfMTFwYmM/view?usp=sharing
If you know a solution of this problem please post it. Thanks
You load image as GL_RGB, you want GL_RGBA to have an alpha channel.
Also, you need a 32 bits Bitmap (8 bits/channel × 4 channels = 32 bits).
I've written a program for testing rendering a texture with the framebuffer. In the function render_texture() I want to render a triangle on to a texture, but when I display the rendered texture in the display function, I get just a simple yellow square.
#include "GL/glew.h"
#include "GL/glext.h"
#include "GL/glu.h"
#include "GL/freeglut.h"
#include <cstdio>
uint16_t tex_width = 75;
uint16_t tex_height = 24;
GLuint texture;
int w1;
int h1;
void orthogonalStart (int w, int h) {
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();
gluOrtho2D(0, w, 0, h);
glScalef(1, -1, 1);
glTranslatef(0, -h1, 0);
glMatrixMode(GL_MODELVIEW);
}
void orthogonalEnd (void) {
glMatrixMode(GL_PROJECTION);
glPopMatrix();
glMatrixMode(GL_MODELVIEW);
}
void display (void) {
glClearColor (0.0,0.0,0.0,1.0);
glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
orthogonalStart(w1, h1);
glBegin(GL_QUADS);
glTexCoord2f(0, 0); glVertex2f(125, 125);
glTexCoord2f(0, 1); glVertex2f(125, 125+tex_height);
glTexCoord2f(1, 1); glVertex2f(125+tex_width, 125+tex_height);
glTexCoord2f(1, 0); glVertex2f(125+tex_width, 125);
glEnd();
orthogonalEnd();
glutSwapBuffers();
}
void reshape (int w, int h) {
glViewport (0, 0, (GLsizei)w, (GLsizei)h);
glMatrixMode (GL_PROJECTION);
glLoadIdentity ();
gluPerspective (60, (GLfloat)w / (GLfloat)h, 0.1, 1000.0);
w1 = w;
h1 = h;
glMatrixMode (GL_MODELVIEW);
}
void render_texture()
{
GLuint framebuffer = 0;
glGenFramebuffers(1, &framebuffer);
glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_2D, texture);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tex_width, tex_height, 0, GL_RGBA,
GL_UNSIGNED_BYTE, 0);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
GLenum draw_buffers[1] = {GL_COLOR_ATTACHMENT0};
glDrawBuffers(1, draw_buffers);
if(glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
{
fprintf(stderr, "[render_texture] Fehler im Framebuffer\n");
exit(1);
}
glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
glViewport(0, 0, tex_width, tex_height);
glClearColor (0.0,0.0,0.0,1.0);
orthogonalStart(tex_width, tex_height);
glColor4f(1, 1, 0, 0);
glBegin(GL_TRIANGLES);
glVertex2f(0.f,0.f);
glVertex2f(tex_width, 0.0f);
glVertex2f(tex_width, (GLfloat)tex_height/2.f);
//glVertex2f(tex_width-(GLfloat)tex_height/2.f, tex_height);
//glVertex2f(0, tex_height);
glEnd();
orthogonalEnd();
glBindFramebuffer(GL_FRAMEBUFFER, 0);
}
int main (int argc, char **argv) {
glutInit (&argc, argv);
glutInitDisplayMode (GLUT_DOUBLE | GLUT_DEPTH | GLUT_RGBA);
glutInitWindowSize (500, 500);
glutInitWindowPosition (100, 100);
glutCreateWindow ("");
glutDisplayFunc (display);
glutIdleFunc (display);
glutReshapeFunc (reshape);
glewExperimental=true;
GLenum err=glewInit();
if(err!=GLEW_OK)
{
//Problem: glewInit failed, something is seriously wrong.
fprintf(stderr, "glewInit failed, aborting.\n");
}
render_texture();
glutMainLoop ();
return 0;
}
Edit 1: I've updated the code, now I have just a blank black screen
#include "GL/glew.h"
#include "GL/glext.h"
#include "GL/glu.h"
#include "GL/freeglut.h"
#include <cstdio>
uint16_t tex_width = 75;
uint16_t tex_height = 24;
GLuint texture;
void orthogonalStart (int w, int h) {
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();
gluOrtho2D(0, w, 0, h);
glScalef(1, -1, 1);
glTranslatef(0, -glutGet(GLUT_WINDOW_HEIGHT), 0);
glMatrixMode(GL_MODELVIEW);
}
void orthogonalEnd (void) {
glMatrixMode(GL_PROJECTION);
glPopMatrix();
glMatrixMode(GL_MODELVIEW);
}
void display (void) {
glClearColor (0.0,0.0,0.0,1.0);
glClear (GL_COLOR_BUFFER_BIT);
glLoadIdentity();
orthogonalStart(glutGet(GLUT_WINDOW_WIDTH), glutGet(GLUT_WINDOW_HEIGHT));
glColor3f(1,1,1);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, texture);
glBegin(GL_QUADS);
glTexCoord2f(0, 0); glVertex2f(125, 125);
glTexCoord2f(0, 1); glVertex2f(125, 125+tex_height);
glTexCoord2f(1, 1); glVertex2f(125+tex_width, 125+tex_height);
glTexCoord2f(1, 0); glVertex2f(125+tex_width, 125);
glEnd();
glDisable(GL_TEXTURE_2D);
orthogonalEnd();
glutSwapBuffers();
}
void reshape (int w, int h) {
glViewport (0, 0, (GLsizei)w, (GLsizei)h);
glMatrixMode (GL_PROJECTION);
glLoadIdentity ();
gluPerspective (60, (GLfloat)w / (GLfloat)h, 0.1, 1000.0);
glMatrixMode (GL_MODELVIEW);
}
void render_texture()
{
GLuint framebuffer = 0;
glGenFramebuffers(1, &framebuffer);
glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_2D, texture);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tex_width, tex_height, 0, GL_RGBA,
GL_UNSIGNED_BYTE, 0);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
GLenum draw_buffers[1] = {GL_COLOR_ATTACHMENT0};
glDrawBuffers(1, draw_buffers);
if(glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
{
fprintf(stderr, "[render_texture] Fehler im Framebuffer\n");
exit(1);
}
glViewport(0, 0, tex_width, tex_height);
glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
orthogonalStart(tex_width, tex_height);
glColor4f(1, 1, 0, 0);
glBegin(GL_TRIANGLES);
glVertex2f(0.f,0.f);
glVertex2f(tex_width, 0.0f);
glVertex2f(tex_width, (GLfloat)tex_height/2.f);
//glVertex2f(tex_width-(GLfloat)tex_height/2.f, tex_height);
//glVertex2f(0, tex_height);
glEnd();
orthogonalEnd();
glBindFramebuffer(GL_FRAMEBUFFER, 0);
}
int main (int argc, char **argv) {
glutInit (&argc, argv);
glutInitContextVersion(3, 1);
glutInitContextProfile(GLUT_CORE_PROFILE);
glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGBA);
glutInitWindowSize (500, 500);
glutCreateWindow ("");
glutDisplayFunc (display);
glutIdleFunc (display);
glutReshapeFunc (reshape);
glewExperimental=true;
GLenum err=glewInit();
if(err!=GLEW_OK)
{
//Problem: glewInit failed, something is seriously wrong.
fprintf(stderr, "glewInit failed, aborting.\n");
}
//glEnable(GL_TEXTURE_2D);
render_texture();
glutMainLoop ();
return 0;
}
You are clearly doing something wrong in the setup of your projection matrix.
I'm not sure why you are calling glScalef() and glTranslatef(), if you comment out these lines in your orthogonalStart() function, you'll have your triangle.
void orthogonalStart (int w, int h) {
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();
gluOrtho2D(0, w, 0, h);
//glScalef(1, -1, 1);
//glTranslatef(0, -glutGet(GLUT_WINDOW_HEIGHT), 0);
glMatrixMode(GL_MODELVIEW);
}
On a sidenote, there is no need to call glBindFramebuffer(GL_FRAMEBUFFER, framebuffer) a 2nd time in your render_texture() function call.
Also, I would recommend you to start learning about vertex buffers to draw your objects, which is more elaborated here.
I'm attempting to render a texture that has been mapped to the graphics video memory. I have used qDebug to test that input of my image, indeed it possesses a 512x512 image which is a power of 2. Yet still when I attempt to render, instead of a texture the result is merely a quad which is white.
To note: GLuint m_textureIdents[1]; is correctly defined in GLWidget.h
#include "GLWidget.h"
GLWidget::GLWidget(QWidget *parent) : QGLWidget(parent)
{
setMouseTracking(true);
m_sceneIndex = SinQuest::SplashScreen;
}
void GLWidget::setApplicationPath(QString strAppPath)
{
m_strAppPath = strAppPath;
}
#include <QDebug>
void GLWidget::loadResources(void)
{
m_imageHandler.addImage(QString(m_strAppPath).append(QDir().toNativeSeparators("\\resources\\images\\")).append("splash_logo.png"), "splash-logo");
QImage glImageData = QGLWidget::convertToGLFormat(*m_imageHandler.getImage("splash-logo"));
qDebug() << glImageData.width() << ":" << glImageData.height();
m_textureIdents[0] = 0;
glGenTextures(1, &m_textureIdents[0]);
glBindTexture(GL_TEXTURE_2D, m_textureIdents[0]);
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
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_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, glImageData.width(), glImageData.height(), 0, GL_RGB, GL_UNSIGNED_BYTE, glImageData.bits());
}
void GLWidget::initializeGL()
{
glEnable(GL_TEXTURE_2D);
glDisable(GL_DEPTH_TEST);
glDisable(GL_COLOR_MATERIAL);
glEnable(GL_BLEND);
glEnable(GL_POLYGON_SMOOTH);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glClearColor(0, 0, 0, 0);
}
void GLWidget::resizeGL(int w, int h)
{
glViewport(0, 0, w, h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0, w, 0, h, -1.0l, 1.0l); // set up origin
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
void GLWidget::paintGL()
{
glClearColor( 0.0f, 0.0f, 0.0f, 0.0f);
glClear( GL_COLOR_BUFFER_BIT );
glMatrixMode( GL_MODELVIEW );
glLoadIdentity();
glColor3f(1.0f, 1.0f, 1.0f);
glShadeModel( GL_FLAT );
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, m_textureIdents[0]);
glBegin(GL_QUADS);
glTexCoord2f(0.0f, 0.0f);
glVertex2i(0, 0);
glTexCoord2f(1.0f, 0.0f);
glVertex2i(512, 0);
glTexCoord2f(1.0f, 1.0f);
glVertex2i(512, 512);
glTexCoord2f(0.0f, 1.0f);
glVertex2i(0, 512);
glEnd();
}
void GLWidget::mousePressEvent(QMouseEvent *event) {
}
void GLWidget::mouseMoveEvent(QMouseEvent *event) {
printf("%d, %d\n", event->x(), event->y());
}
void GLWidget::keyPressEvent(QKeyEvent* event) {
switch(event->key()) {
case Qt::Key_Escape:
close();
break;
default:
event->ignore();
break;
}
}
...
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
QDesktopWidget *pDeskWidget = app.desktop();
// available geometry to obtain resolution for primary screen
QRect avGeometry = pDeskWidget->availableGeometry(pDeskWidget->primaryScreen());
// create window, set resolution and invoke fullscreen window state
GLWidget window;
window.setApplicationPath(QCoreApplication::applicationDirPath());
window.loadResources();
window.resize(avGeometry.width(), avGeometry.height());
window.setWindowState(Qt::WindowFullScreen);
window.show();
return app.exec();
}