C++/Qt, OpenGL texture mapping - c++

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();
}

Related

How do you put textures on square with OpenGL?

I tried to apply textures to squares with the following code, but they didn't apply.
Is there a problem with the code above?
"dd" is printed on the console window.
I think it is read the bmp file.
but I only see white square like the following pictures.
Bitmap files are located in the project folder.
LoadBMP() is a function that opens the bmp file.
LoadGLTextures() is a function to load textures.
ps. I am not good at English. I'm sorry.
#define _CRT_SECURE_NO_DEPRECATE
#include <windows.h>
#include <GL/gl.h>
#include <GL/glu.h>
#include <GL/glut.h>
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#include <GL/GLAUX.H>
#pragma comment (lib,"glaux.lib")
unsigned int MyTextureObiect[1];
AUX_RGBImageRec *pTextureImage[1];
AUX_RGBImageRec *LoadBMP(char *szFilename) {
FILE * pFile = NULL;
if (!szFilename) {
return NULL;
}
pFile = fopen(szFilename, "r");
if (pFile) {
fclose(pFile);
return auxDIBImageLoad(szFilename);
}
return NULL;
}
int LoadGLTextures() {
int Status = FALSE;
memset(pTextureImage, 0, sizeof(void *) * 1);
if (pTextureImage[0] = LoadBMP("butterflyans.bmp")) {
printf("dd");
Status = TRUE;
glGenTextures(1, &MyTextureObiect[0]);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexImage2D(GL_TEXTURE_2D, 0, 3, pTextureImage[0]->sizeX, pTextureImage[0]->sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE, pTextureImage[0]->data);
glEnable(GL_TEXTURE_2D);
}
if (pTextureImage[0]) {
if (pTextureImage[0]->data) {
free(pTextureImage[0]->data);
}
free(pTextureImage[0]);
}
return Status;
}
void myDisplay(void)
{
glClear(GL_COLOR_BUFFER_BIT);
glBindTexture(GL_TEXTURE_2D, MyTextureObiect[0]);
glBegin(GL_QUADS);
glTexCoord2f(0.0f, 0.0f);
glVertex3f(-0.5, -0.5, 0.0);
glTexCoord2f(1.0f, 0.0f);
glVertex3f(0.5, -0.5, 0.0);
glTexCoord2f(1.0f, 1.0f);
glVertex3f(0.5, 0.5, 0.0);
glTexCoord2f(0.0f, 1.0f);
glVertex3f(-0.5, 0.5, 0.0);
glEnd();
glFlush();
}
int main(int argc, char **argv)
{
glutInit(&argc, argv);
glutCreateWindow("OpenGL Drawing Example");
glutDisplayFunc(myDisplay);
if (LoadGLTextures()) {
glEnable(GL_TEXTURE_2D);
}
glutMainLoop();
return 0;
}
You missed to bind glBindTexture the texture object, before setting the texture parameters and specifying the texture.
Note, glTexParameter and glTexImage2D apply to the currently bound texture:
glGenTextures(1, &MyTextureObiect[0]);
glBindTexture(GL_TEXTURE_2D, MyTextureObiect[0]); // <---- bind the texture
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexImage2D( .... );
By the way, you set GL_TEXTURE_MIN_FILTER twice, but you never set GL_TEXTURE_MAG_FILTER.

glut cannot plot a 2D image

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.

QOpenGLWidget Texture Mapping results in Black screen

I am trying to render a simple 2d Image with the QOpenGLWidget using a quad as a texture. But no matter what I am trying, I always get a black box.
I have read many tutorials, I have a simple pixelbuffer like this
uchar* m_pData;
which stores my RGB values. This is valid, since I have it tested with glDrawPixles(). I will post the three most important functions considering the OpenGLWidget.
initializeGL() first:
void QGLImageviewer::initializeGL()
{
initializeOpenGLFunctions();
// Clear the color
float r = ((float)m_backColor.darker().red())/255.0f;
float g = ((float)m_backColor.darker().green())/255.0f;
float b = ((float)m_backColor.darker().blue())/255.0f;
glClearColor(r,g,b,1.0f);
// Set shading model.
glShadeModel(GL_SMOOTH);
// Set the viewport
glViewport(0.f, 0.f, m_origW, m_origH);
// Init. Projection Matrix
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0.0, m_origW, m_origH,0.0,1.0,-1.0);
// Init Modelview Matrix
glClearColor(0.f, 0.f, 0.f, 1.f);
// Enable texturing
glEnable(GL_TEXTURE_2D);
// Generate texture ID
glGenTextures(1, &m_textureID);
// Bind texture ID
glBindTexture(GL_TEXTURE_2D, m_textureID);
// Set texture parameters
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
//glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
//glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
// Generate Texture, and assign pixles to our texture ID
if (m_pData != nullptr)
{
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, m_origW, m_origH, 0, GL_RGB, GL_UNSIGNED_BYTE, (GLvoid*)m_pData);
}
else
{
qCritical("Buffer is empty!!");
}
// Unbind texture
glBindTexture(GL_TEXTURE_2D, NULL);
// Check for Error
GLenum error_ = glGetError();
if (error_ != GL_NO_ERROR)
{
qCritical("Error Loading Texture!");
}
}
Then paintGL():
void QGLImageviewer::paintGL()
{
makeCurrent();
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
// Clear Screen And Depth Buffer
glClear(GL_COLOR_BUFFER_BIT);
if (!(m_renderQtImg->isNull()))
{
//QImage image;
int imWidth = m_renderQtImg->width();
int imHeight = m_renderQtImg->height();
// The image has to be resized to fit the widget
if (imWidth != this->size().width() &&
imHeight != this->size().height())
{
imWidth = this->size().width();
imHeight = this->size().height();
}
else
{
//image = *m_renderQtImg;
imWidth = m_origW;
imHeight = m_origH;
}
if (m_textureID != 0)
{
glMatrixMode(GL_MODELVIEW);
// Remove any previous transformations
glLoadIdentity();
glPushMatrix();
// Move to rendering point
glTranslatef(0.f, 0.f, 0.f);
glColor3f(0.0f, 0.0f, 0.5f);
// Set texture ID
glBindTexture(GL_TEXTURE_2D, m_textureID);
glBegin(GL_QUADS);
glTexCoord2f(0.f, 0.f); glVertex2f(0.f, 0.f);
glTexCoord2f(1.f, 0.f); glVertex2f(imWidth, 0.f);
glTexCoord2f(1.f, 1.f); glVertex2f(imWidth, imHeight);
glTexCoord2f(0.f, 1.f); glVertex2f(0.f, imHeight);
glEnd();
//glDisable(GL_TEXTURE_2D);
glPopMatrix();
glFlush();
}
}
}
And last but not least resizeGL():
void QGLImageviewer::resizeGL(int width, int height)
{
makeCurrent();
glViewport(0,0,(GLint)width,(GLint)height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
//gluOrtho2D(0.0, width, 0.0, height);
glOrtho(0.0, width, 0.0, height, 0.0, 1.0);
}
I am using Qt5.6 and the Microsoft Visual Studio 2015 compiler.
Damn, the problem was on
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, m_origW , m_origH, 0, GL_RGB, GL_UNSIGNED_BYTE, (float*)m_pData);
My member variables m_orgiW and m_orgiH were initialized to 0. So quite unsurprising that my code did not work.
For the record I will post my running code, the three most important functions of the QOpenGLWidget, hope that it will be useful to somebody with the same issue.
void QGLImageviewer::initializeGL()
{
initializeOpenGLFunctions();
float r = ((float)m_backColor.darker().red())/255.0f;
float g = ((float)m_backColor.darker().green())/255.0f;
float b = ((float)m_backColor.darker().blue())/255.0f;
glClearColor(r,g,b,1.0f);
// Generate texture ID
glGenTextures(1, &m_textureID);
// Bind texture ID
glBindTexture(GL_TEXTURE_2D, m_textureID);
if (m_pData != nullptr)
{
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, m_origW , m_origH, 0, GL_RGB, GL_UNSIGNED_BYTE, (float*)m_pData);
}
else
{
qCritical("Buffer is empty!!");
}
// Set texture parameters
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); //IMPORTANT FOR NON POWER OF 2 TEXTURES
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
// Enable texturing Mapping
glEnable(GL_TEXTURE_2D);
// Enable Smooth Shading
glShadeModel(GL_SMOOTH);
// Black Background
glClearColor(0.0f, 0.0f, 0.0f, 0.5f);
// Depth Buffer Setup
glClearDepth(1.0f);
// Enables Depth Testing
glEnable(GL_DEPTH_TEST);
// Type of depth testing to do
glDepthFunc(GL_LEQUAL);
// Really Nice Perspective Calculations
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
// Unbind Texture
glBindTexture(GL_TEXTURE_2D, NULL);
}
Now paintGL()
void QGLImageviewer::paintGL()
{
makeCurrent();
// Clear Screen And Depth Buffer
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, m_textureID);
glBegin(GL_QUADS);
// Drawing the quad with the texture mapped on it
//
// OpenGL 2D Coordinates
// Sticking with the Coordinate Convention mentioned here
glTexCoord2f(1.0f, 0.0f); glVertex2f(m_width, 0.0f); // vertex 1
glTexCoord2f(1.0f, 1.0f); glVertex2f(m_width, m_height); // vertex 2
glTexCoord2f(0.0f, 1.0f); glVertex2f(0.0f, m_height); // vertex 3
glTexCoord2f(0.0f, 0.0f); glVertex2f(0.0f, 0.0f); // vertex 4
glEnd();
}
And resizeGL()
void QGLImageviewer::resizeGL(int width, int height)
{
makeCurrent();
m_width = width;
m_height = height;
// Compute aspect ratio of the new window
if (height == 0) height = 1; // To prevent divide by 0
GLfloat aspect = (GLfloat)width / (GLfloat)height;
// Set the viewport to cover the new window
glViewport(0, 0, width, height);
// Set the aspect ratio of the clipping area to match the viewport
glMatrixMode(GL_PROJECTION); // To operate on the Projection matrix
glLoadIdentity(); // Reset the projection matrix
glOrtho(0, m_width/ m_zoomFactor, m_height/ m_zoomFactor,0, -1, 1);
}

opengl: rendering to texture goes wrong

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.

Scene in upper right corner of OpenGL window without using glOrtho

Essentially, I'm rendering a raw buffer of pixels onto a texture, which is wrapped onto a quad.
My GL initiation code:
void INITOGL(int xres, int yres){
glShadeModel(GL_SMOOTH);
glClearColor(0.0f, 0.0f, 0.0f, 0.5f);
glClearDepth(1);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
//gluOrtho2D(0, xres, 0, yres);
}
Render loop code:
void RenderCycle(){
register MSG msg = {0};
while(1){
if(PeekMessage(&msg, 0, 0, 0, PM_REMOVE)){
TranslateMessage(&msg);
DispatchMessage(&msg);
}
glEnable(GL_TEXTURE_2D);
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_NEAREST);//GL_LINEAR
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE/*GL_DECAL*/);
glTexImage2D( GL_TEXTURE_2D, 0, 3, 800, 600, 0, GL_RGB, GL_UNSIGNED_BYTE, framebuffer);//viewport virtual size
glClear(GL_COLOR_BUFFER_B
IT | GL_DEPTH_BUFFER_BIT);
glBegin(GL_POLYGON);
glTexCoord2f(0.0f, 1.0f);
glVertex3f(0, 0, 0.0f);
glTexCoord2f(1.0f, 1.0f);
glVertex3f( 800, 0, 0.0f);
glTexCoord2f(1.0f, 0.0f);
glVertex3f( 800, 600, 0.0f);
glTexCoord2f(0.0f, 0.0f);
glVertex3f( 0, 600, 0.0f);
glEnd();
glDisable(GL_TEXTURE_2D);
SwapBuffers(hdc);
}
}
The resize function:
void ResizeViewport(int height, int width){
if(!height)height++;
//glMatrixMode(GL_MODELVIEW);
//glLoadIdentity();
//gluPerspective(45.0f,(GLfloat)width/(GLfloat)height,0.1f,100.0f);
glMatrixMode(GL_PROJECTION);
glViewport(0,0,width,height);
//gluOrtho2D(0, width, 0, height);
glLoadIdentity();
}
The buffer that holds the RGB data is just set to red using a for loop, and this is the output.
Have I improperly set my viewport, not scaled something correctly, or am I just completely missing something? If you need any more information, just ask. I have given all of the opengl sided code, the rest shouldn't make a difference. In theory, it should render red to the entire screen.