Rendering a second pass yields a different result - c++

Currently I'm trying to render multiple passes with different shaders in a simple OpenGL application. Here's my (simplified) code:
void InitScene()
{
glViewport(0, 0, mWindowWidth, mWindowHeight);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0, mWindowWidth, mWindowHeight, 0, -1, 1);
mFramebufferName = CreateFrameBuffer(mWindowWidth, mWindowHeight);
}
void DrawScene()
{
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
if(drawDirectlyToScreen)
{
// This works fine, image will fill the whole screen
// Directly draw to the screen
DrawFullScreenQuad();
}
else
{
// This does not work. The image from the first pass will only be a small quadrat
// Draw to frame buffer instead of screen
glBindFramebuffer(GL_FRAMEBUFFER, mFramebufferName);
DrawFullScreenQuad();
glBindFramebuffer(GL_FRAMEBUFFER, 0);
// Get ready for second pass
BindFrameBufferTextureAndActivateAnotherShader();
// Now draw to the screen
DrawFullScreenQuad();
}
glPopMatrix();
}
void DrawFullScreenQuad()
{
glBegin(GL_QUADS);
glTexCoord2f(0.0f, 1.0f); glVertex3f(0.0f, mWindowHeight, 0.0f);
glTexCoord2f(1.0f, 1.0f); glVertex3f(mWindowWidth, mWindowHeight, 0.0f);
glTexCoord2f(1.0f, 0.0f); glVertex3f(mWindowWidth, 0.0f, 0.0f);
glTexCoord2f(0.0f, 0.0f); glVertex3f(0.0f, 0.0f, 0.0f);
glEnd();
}
void CreateFrameBuffer(int width, int height)
{
// Generate and bind the frame buffer
mFramebufferName = 0;
glGenFramebuffers(1, &mFramebufferName);
glBindFramebuffer(GL_FRAMEBUFFER, mFramebufferName);
// Create and bind the render texture
glGenTextures(1, &mSecondPassRenderTexture);
glBindTexture(GL_TEXTURE_2D, mSecondPassRenderTexture);
// Give an empty image to OpenGL ( the last "0" )
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);
// Set "mSecondPassRenderTexture" as colour attachement #0
glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, mSecondPassRenderTexture, 0);
// Set the list of draw buffers.
GLenum DrawBuffers[1] = { GL_COLOR_ATTACHMENT0 };
glDrawBuffers(1, DrawBuffers); // "1" is the size of DrawBuffers
}
When rendering only one pass everything is fine. The image covers the whole screen. When rendering with two passes, the resulting image will only cover a small square area in the top left corner of the screen (see the attached images).
The problem seems to come from the first pass. The texture created in that pass is already wrong (i.e. the image is only in the corner, the rest of the texture is black). The second pass then works correctly (i.e. the broken texture is drawn correctly to the whole screen).
So my question is: why does my call to DrawFullScreenQuad() yield different results when
Rendering to the screen directly
Rendering to a frame buffer (which has the same size as the window)

Related

Using glTexImage2D to render to texture, blank result. (Dreamcast GLdc)

I am trying to create a quick render to texture example using GLdc, a OpenGL implementation for the Sega Dreamcast. I have verified that both my Texture and Framebuffer Object are complete, yet the texture resulting from the framebuffer only has 1 white dot in it.
First, I generate an empty texture and prepare it to be written to.
func genTextures(){
glGenTextures(1, &renderedTexture[0]);
glBindTexture(GL_TEXTURE_2D, renderedTexture[0]);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR); // scale linearly when image smaller than texture
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 128, 128, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
}
Next, I generate an FBO and bind the new texture we just created to it.
func genFBO() {
glGenFramebuffersEXT(1, &fbo);
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo);
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT,
GL_TEXTURE_2D, renderedTexture[0], 0);
}
At this point the FBO and the Texture should both be considered complete. The main loop is structured something like this:
int main(int argc, char **argv)
{
glKosInit();
InitGL(640, 480);
ReSizeGLScene(640, 480);
genTextures();
genFBO();
while(1) {
if(check_start())
break;
// I checked here for FBO and Texture completeness, both return True.
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo); // bind to the FBO
DrawGLScene(); // Draw our cube to the FBO
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); // back to default
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
ReSizeGLScene(640,480);
DrawGLUI(); //Draw the quad with the framebuffers texture
}
return 0;
}
Here are the two functions that draw geometry:
void DrawGLScene()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);// Clear The Screen And The Depth Buffer
glLoadIdentity(); // Reset The View
glTranslatef(0.0f,0.0f,-5.0f); // move 5 units into the screen.
glRotatef(xrot,1.0f,0.0f,0.0f); // Rotate On The X Axis
glRotatef(yrot,0.0f,1.0f,0.0f); // Rotate On The Y Axis
glRotatef(zrot,0.0f,0.0f,1.0f); // Rotate On The Z Axis
glBindTexture(GL_TEXTURE_2D, texture[0]); // choose the texture to use.
glBegin(GL_QUADS); // begin drawing a cube
// Draw my textured cube, works fine.
glEnd(); // done with the polygon.
xrot+=1.5f; // X Axis Rotation
yrot+=1.5f; // Y Axis Rotation
zrot+=1.5f; // Z Axis Rotation
glKosSwapBuffers();
}
void DrawGLUI(){
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glClearColor(0.0f, 0.0f, 0.0f, 0.0f); // This Will Clear The Background Color To Black
glClearDepth(1.0); // Enables Clearing Of The Depth Buffer
glLoadIdentity();
glMatrixMode(GL_PROJECTION);
glDisable(GL_DEPTH_TEST);
glEnable(GL_TEXTURE_2D);
glLoadIdentity();
glBindTexture(GL_TEXTURE_2D, renderedTexture[0]);
glBegin(GL_QUADS);
//glColor3f(1.0f, 0.0f, 0.0);
glTexCoord2f(0.0, 0.0); glVertex2f(0.0, 0.0);
glTexCoord2f(1.0, 0.0); glVertex2f(1.0, 0.0);
glTexCoord2f(1.0, 1.0); glVertex2f(1.0, 1.0);
glTexCoord2f(0.0, 1.0); glVertex2f(0.0, 1.0);
glEnd();
glEnable(GL_DEPTH_TEST);
ReSizeGLScene(640,480);
glFlush();
}
The result is
Where I would like to have the cube rendered to a texture then that texture applied to the quad in the upper right corner...
The size of the viewport must be adjusted to the size of the framebuffer with glViewport when the framebuffer is switched:
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo);
glViewport(0, 0, 128, 128);
// [...]
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
glViewport(0, 0, 640, 480);
// [...]

Render FFmpeg AVFrame as OpenGL texture?

I'm attempting to to render a jpeg image (1024x1024 pixels) in the form of an FFmpeg AVFrame as a texture in OpenGL. What I get instead is something that appears as a 1024x1024 dark green quad:
The code to render the AVFrame data in OpenGL is shown below. I have convinced myself that the raw RGB data held within the FFmpeg AVFrame data is not solely dark green.
GLuint g_texture = {};
//////////////////////////////////////////////////////////////////////////
void display()
{
// Clear color and depth buffers
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW); // Operate on model-view matrix
glEnable(GL_TEXTURE_2D);
GLuint texture = g_texture;
glBindTexture(GL_TEXTURE_2D, texture);
// Draw a quad
glBegin(GL_QUADS);
glVertex2i(0, 0); // top left
glVertex2i(1024, 0); // top right
glVertex2i(1024, 1024); // bottom right
glVertex2i(0, 1024); // bottom left
glEnd();
glDisable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, 0);
glFlush();
}
/* Initialize OpenGL Graphics */
void initGL(int w, int h)
{
glViewport(0, 0, w, h); // use a screen size of WIDTH x HEIGHT
glEnable(GL_TEXTURE_2D); // Enable 2D texturing
glMatrixMode(GL_PROJECTION); // Make a simple 2D projection on the entire window
glOrtho(0.0, w, h, 0.0, 0.0, 100.0);
glMatrixMode(GL_MODELVIEW); // Set the matrix mode to object modeling
//glTranslatef( 0, 0, -15 );
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
glClearDepth(0.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Clear the window
}
//////////////////////////////////////////////////////////////////////////
int main(int argc, char *argv[])
{
std::shared_ptr<AVFrame> apAVFrame;
if (!load_image_to_AVFrame(apAVFrame, "marble.jpg"))
{
assert(false);
return 1;
}
// From here on out, the AVFrame is RGB interleaved
// and is sized to 1,024 x 1,024 (power of 2).
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGB | GLUT_SINGLE);
glutInitWindowSize(1060, 1060);
glutInitWindowPosition(0, 0);
glutCreateWindow("OpenGL - Creating a texture");
glGenTextures(1, &g_texture);
//glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
glBindTexture(GL_TEXTURE_2D, g_texture);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, apAVFrame->width,
apAVFrame->height, 0, GL_RGB, GL_UNSIGNED_BYTE,
apAVFrame->data[0]);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); /* We will use linear interpolation for magnification filter */
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); /* We will use linear interpolation for minifying filter */
initGL(1060, 1060);
glutDisplayFunc(display);
glutMainLoop();
return 0;
}
Environment:
Ubuntu 18.04
GCC v8.2
EDIT: As per #immibis' suggestion below, it all works when I change the rendering of the quad to:
// Draw a quad
glBegin(GL_QUADS);
glTexCoord2f(0, 0);
glVertex2i(0, 0); // top left
glTexCoord2f(1, 0);
glVertex2i(1024, 0); // top right
glTexCoord2f(1, 1);
glVertex2i(1024, 1024); // bottom right
glTexCoord2f(0, 1);
glVertex2i(0, 1024); // bottom left
glEnd();
You forgot to give your vertices texture coordinates, so all the pixels on your screen are reading the same pixel from the texture. (The top-left, or wherever the default texture coordinates are)
Use glTexCoord2f before glVertex2i to set the texture coordinates for the vertex. They go from 0 on the top/left of the texture, to 1 on the bottom/right, so the corners of the texture are 0,0, 1,0, 1,1 and 0,1.

openGL, text changes when I load textures

I'm developing a C++ application and I need to use an interface made in openGL. I have a grey background, some squared textures over the background and some text written next to the textures. The text is yellow but when I click with mouse on the window or I change the textures, the text turns grey (a different grey from the background) and I don't know why! Here is the code and screenshots:
int main(int argc, char** argv){
[...]
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);
glShadeModel(GL_FLAT);
glEnable(GL_BLEND);
glEnable(GL_POINT_SMOOTH);
// Render the scene
glutDisplayFunc(display);
glutReshapeFunc(reshape);
// Turn the flow of control over to GLUT
glutMainLoop();
[...]
}
void display(void){
glClearColor(0.2f, 0.2f, 0.2f, 0.5f); //Background color
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// Set up viewing transformation, looking down -Z axis
glLoadIdentity();
gluLookAt(posx, 0, -g_fViewDistance, 0, 0, -1, 0, 1, 0);
// Render the scene
glMatrixMode(GL_COLOR);
glColor3f(1.0f, 1.0f, 0.0f); // Textcolor
drawOnScreen(); // Draw text on screen
glMatrixMode(GL_MODELVIEW);
loadSquare(); // Load texture
glutSwapBuffers();
}
void reshape(GLint width, GLint height){
interface->setWindowWidth(width);
interface->setWindowHeight(height);
glViewport(0, 0, g_Width, g_Height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(65.0, (float)g_Width / g_Height, g_nearPlane, g_farPlane);
glMatrixMode(GL_MODELVIEW);
}
void printStringOnVideo(void* font, char* s){
if (s && strlen(s)) {
while (*s) {
glutBitmapCharacter(font, *s);
s++;
}
}
}
void drawOnScreen(){
GLfloat x, y;
// Draw the strings, according to the current mode and font.
x = 2.90f;
y = 0.80f;
glRasterPos2f(x, y);
int len;
char s[] = { 'H', 'E', 'L', 'L', 'O', '\0' };
len = (int)strlen(s);
printStringOnVideo(GLUT_BITMAP_TIMES_ROMAN_24, s);
}
The loadSquare() function applies texture to squares. Its main feature is calling the class method for loading textures on squares:
void P300Square::setTexture(bool func){
// Se func = 0 allora carico la texture, viceversa il flash
string tmp = "";
if (func == false)
tmp = texturePath;
else
tmp = textureFlashPath;
GLuint texture = SOIL_load_OGL_texture
(
tmp.c_str(),
SOIL_LOAD_AUTO,
SOIL_CREATE_NEW_ID,
SOIL_FLAG_NTSC_SAFE_RGB | SOIL_FLAG_COMPRESS_TO_DXT
);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, texture);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
glColor3ub(50, 50, 50);
glEnable(GL_BLEND);
glBegin(GL_QUADS);
glColor4f(0.5f, 0.0, 0.0f, 0.8f);
// Top Left
glTexCoord2f(0, 1);
glVertex2f(u, v);
// Top Right
glTexCoord2f(1, 1);
glVertex2f(u + size, v);
// Bottom Right
glTexCoord2f(1, 0);
glVertex2f(u + size, v + size);
// Bottom Left
glTexCoord2f(0, 0);
glVertex2f(u, v + size);
glEnd();
glDisable(GL_BLEND);
}
Can please someone help me? Thank you!
You should disable GL_TEXTURE_2D before you draw the bitmap font.
Internally, glutBitmapCharacter() uses glBitmap. This function maps the bitmap to a rectangle to the screen and generates a fragment for every framebuffer pixel in that rectangle where the bitmap is 1. Those fragments get the associated data from the values associated with the current raster position.
The generated fragments are processed like every other fragment (i.e. the ones generated by drawing primitives like lines or triangles). So stuff like texturing, lighting, fog, blending and so on will also affect everything drawn by glBitmap. Due to the fact that all fragments generated by a single bitmap get the same associated data, they all will get the same texture coordinate. Since you left texturing on, the GL textures all of these fragments with the very same sample from the texture, so that they all appear in the same color.

OpenGL Rendering to Multiple Textures, results are white

I've begun switching my rendering code to support shaders, and that all works fine when rendering to the back buffer. So now I'm working towards rendering to FBOs, but all I get are white textures for both the color and normals.
Here is my FBO creation code:
void RenderTarget_GL::CreateFBO (void)
{
// if the machine supports the GL FBO extension
if (s_supportfbo)
{
// Create FBO
glGenFramebuffersEXT(1, &m_fbo);
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_fbo);
// Create default texture buffer
char *buffer = new char [static_cast<int>(g_window->GetWidth() * m_screenWidth) * static_cast<int>(g_window->GetHeight() * m_screenHeight) * 4];
std::memset(buffer, 0, static_cast<int>(g_window->GetWidth() * m_screenWidth) * static_cast<int>(g_window->GetHeight() * m_screenHeight) * 4);
// Create Render Texture
glGenTextures(1, &m_rendertexture);
glBindTexture(GL_TEXTURE_2D, m_rendertexture);
glTexImage2D(GL_TEXTURE_2D, 0, 4, static_cast<int>(g_window->GetWidth() * m_screenWidth), static_cast<int>(g_window->GetHeight() * m_screenHeight), 0, GL_RGBA, GL_UNSIGNED_BYTE, buffer);
// Bind Render Texture to FBO
glBindTexture(GL_TEXTURE_2D, 0);
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, m_rendertexture, 0);
// Create Normal Texture if this FBO will be rendering normals
if (m_hasnormal)
{
glGenTextures(1, &m_normaltexture);
glTexImage2D(GL_TEXTURE_2D, 0, 4, static_cast<int>(g_window->GetWidth() * m_screenWidth), static_cast<int>(g_window->GetHeight() * m_screenHeight), 0, GL_RGBA, GL_UNSIGNED_BYTE, buffer);
// Bind Normal Texture to FBO
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT1_EXT, GL_TEXTURE_2D, m_normaltexture, 0);
}
// UnBind FBO and cleanup default buffer
delete [] buffer;
Clear();
}
}
And the code I use to set the current render target:
void RenderTarget_GL::Set (void)
{
if (s_supportfbo && g_glgraphics->GetShaderEnabled())
{
static const GLenum buffer1[] = {GL_COLOR_ATTACHMENT0_EXT};
static const GLenum buffer2[] = {GL_COLOR_ATTACHMENT0_EXT, GL_COLOR_ATTACHMENT1_EXT};
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_fbo);
if (m_hasnormal)
glDrawBuffers(2, buffer2);
else
glDrawBuffers(1, buffer1);
}
}
And finally, my actual drawing code:
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
// Setup the camera transformation
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
if (m_camera)
m_camera->GLMatrix();
else
m_defaultCam.GLMatrix();
// Setup Render Target
if (m_shaderenabled)
{
glPushAttrib(GL_VIEWPORT_BIT);
glViewport(0,0,g_window->GetWidth(),g_window->GetHeight());
m_initialpass->Set();
}
// Draw All Objects with their per-object shaders
// Clear render target and shader bindings
if (m_shaderenabled)
{
glPopAttrib();
RenderTarget_GL::Clear();
Shader_GL::ClearShaderBinding();
}
glPopMatrix();
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();
// Draw Scene
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, m_initialpass->GetColorTexture());
glBegin(GL_QUADS);
glTexCoord2f(0.0f, 0.0f);
glVertex3f(-1.0f, -1.0f, 0.0f);
glTexCoord2f(1.0f, 0.0f);
glVertex3f(1.0f, -1.0f, 0.0f);
glTexCoord2f(1.0f, 1.0f);
glVertex3f(1.0f, 1.0f, 0.0f);
glTexCoord2f(0.0f, 1.0f);
glVertex3f(-1.0f, 1.0f, 0.0f);
glEnd();
Texture_GL::ClearTextureBinding();
glPopMatrix();
// Swap Buffers
GL_TEXTURE_MIN_FILTER is GL_NEAREST_MIPMAP_LINEAR by default. Supply mipmaps or switch to GL_LINEAR or GL_NEAREST.
The OpenGL Wiki has more.

Qt Vertex Arrays not working with QImage

I'll begin by apologizing for the length of the question. I believe I've committed some small, dumb error, but since I'm entirely unable to find it, I decided to post all relevant code just in case.
I finally got texture loading working using QImage, and am able to render textures in immediate mode.
However, vertex arrays don't work, and I'm at a loss as to why.
The most obvious things like "Have you enabled vertex arrays and texture coordinate arrays?" are probably not the answer. I'll post the initialization code.
Here's the init function:
/* general OpenGL initialization function */
int initGL()
{
glShadeModel(GL_SMOOTH); // Enable Smooth Shading
glClearColor(0, 0, 0, 1); // Black Background
glEnable ( GL_COLOR_MATERIAL );
glColorMaterial ( GL_FRONT, GL_AMBIENT_AND_DIFFUSE );
glDisable(GL_DEPTH_TEST);
//ENABLED VERTEX ARRAYS AND TEXTURE COORDINATE ARRAYS
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glEnableClientState(GL_VERTEX_ARRAY);
//ENABLED 2D TEXTURING
glEnable ( GL_TEXTURE_2D );
glPixelStorei ( GL_UNPACK_ALIGNMENT, 1 );
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
//seed random
srand(time(NULL));
return( TRUE );
}
I have initialization, resize and draw functions that are called by a QGLWidget (which is itself just a skeleton that calls the real work functions)
The texture loading function:
GLuint LoadGLTextures( const char * name )
{
//unformatted QImage
QImage img;
//load the image from a .qrc resource
if(!img.load(":/star.bmp"))
{
qWarning("ERROR LOADING IMAGE");
}
//an OpenGL formatted QImage
QImage GL_formatted_image;
GL_formatted_image = QGLWidget::convertToGLFormat(img);
//error check
if(GL_formatted_image.isNull())
qWarning("IMAGE IS NULL");
else
qWarning("IMAGE NOT NULL");
//texture ID
GLuint _textures[1];
//enable texturing
glEnable(GL_TEXTURE_2D);
//generate textures
glGenTextures(1,&_textures[0]);
//bind the texture
glBindTexture(GL_TEXTURE_2D,_textures[0]);
//texture parameters
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glBindTexture(GL_TEXTURE_2D,_textures[0]);
//generate texture
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, GL_formatted_image.width(),
GL_formatted_image.height(), 0, GL_RGBA, GL_UNSIGNED_BYTE,
GL_formatted_image.bits());
glBindTexture(GL_TEXTURE_2D,_textures[0]);
//return the texture ID
return _textures[0];
}
Here's the draw code:
//this does draw
//get the texture ID
GLuint tex_id = LoadGLTextures(":/star.png");
glBindTexture(GL_TEXTURE_2D, tex_id); // Actually have an array of images
glColor3f(1.0f, 0.0f, 0.5f);
glBegin(GL_QUADS);
glTexCoord2f(1.0f, 0.0f);glVertex2f(1.0f, 0.0f);
glTexCoord2f(1.0f, 1.0f);glVertex2f(1.0f, 1.0f);
glTexCoord2f(0.0f, 1.0f);glVertex2f(0.0f, 1.0f);
glTexCoord2f(0.0f, 0.0f);glVertex2f(0.0f, 0.0f);
glEnd();
//this does not draw
//translations code
glLoadIdentity();
glTranslatef(-1.0f, 0.0f, 0.0f);
//bind the texture
glBindTexture(GL_TEXTURE_2D, tex_id);
//set color state
glColor4f(0.0f, 1.0f, 0.0f, 0.5);
//vertices to be rendered
static GLfloat vertices[] =
{
1.0f, 0.0f,
1.0f, 1.0f,
0.0f, 1.0f,
0.0f, 0.0f
};
static GLshort coord_Data[] =
{
1, 0,
1, 1,
0, 1,
0, 0
};
//bind the texture
glBindTexture(GL_TEXTURE_2D, tex_id);
//pointer to the vertex array
glVertexPointer(2, GL_FLOAT, 0, vertices);
//texture coordinate pointer
glTexCoordPointer(2, GL_SHORT, 0, coord_Data);
//draw the arrays
glDrawArrays(GL_QUADS, 0, 4);
Thanks for all help,
Dragonwrenn
One possibility is that the problem stems from calling glVertexCoordPointer before calling glTexCoordPointer. Weird things happen when you specify the texture coordinate after the vertex coordinate. I know this is true for drawing a single vertex with a texture coordinate. I'm not sure if it's true with arrays.
A few other things...
Have you tried using QPixMap instead of QImage? I doubt this is the answer to your problem since it sounds like the texture is applied to the first quad properly.
There are two calls to bindTexture.
Have you tried just drawing the vertices (without the texture) in the second part of the code?
Finally, do you get any compiler warnings?
The way you place your OpenGL state manipulations, it is difficult to keep track of things. It's a good idea to set OpenGL state on demand. So
Move this
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_TEXTURE_CORRD_ARRAY);
right before
//bind the texture
glBindTexture(GL_TEXTURE_2D, tex_id);
glVertexPointer(2, GL_FLOAT, 0, vertices);
glTexCoordPointer(2, GL_SHORT, 0, coord_Data);
//draw the arrays
glDrawArrays(GL_QUADS, 0, 4);
also you should move the other code from initGL.
Belonging into the texture loader, before supplying the data to glTexImage:
glPixelStorei ( GL_UNPACK_ALIGNMENT, 1 );
Belonging to the beginning of the drawing function:
glShadeModel(GL_SMOOTH);
glClearColor(0, 0, 0, 1);
glEnable( GL_COLOR_MATERIAL );
glColorMaterial ( GL_FRONT, GL_AMBIENT_AND_DIFFUSE );
glDisable(GL_DEPTH_TEST);
Following the scheme you should set viewport and projection matrices in the drawing function, too. I'm just telling this, because most of the tutorials do it differently, which tricks people into thinking this was the right way. Technically projection and viewport and on-demand-states as well.
You should not re-load the texture with every draw call. Note that initializing the texture on demand through the drawing handler is a good idea, you should just add some flag to the texture encapsulating class telling, if the referenced texture is already available to OpenGL.
Just for debugging purposes try changing the type of the texture coordinates to floats.