Note that there are some explanatory texts on larger screens.

plurals
  1. POSDL 3d OpenGL: texture on cube produces blank screen
    primarykey
    data
    text
    <p>I have been trying to load a texture on to a cube using SDL_image and OpenGL. For some reason, the entire window remains blank when I attempt to use textures. By commenting out my texture initialisation call, the window renders as it should, except with a white texture. The same applies when my call to glEnable(GL_TEXTURE_2D) gets commented out. I have been trying for several hours now to fix this, and have spent most of those looking online for whether anyone has come up with a solution, but nothing I tried worked. I have posted only sections of my code below, if more is required, please let me know.</p> <p>OpenGL initialisation (The order for glEnable(GL_TEXTURE_2D) may be incorrect):</p> <pre><code>//Configures OpenGL for 3d rendering //Needs to know the window height and width void setUpOpenGL(int width, int height) { //Enable depth testing, necessary for 3d worlds glEnable(GL_DEPTH_TEST); glEnable(GL_TEXTURE_2D); //Set the background colour to black glClearColor(0.0f, 0.0f, 0.0f, 1.0f); //Set the clear depth at 1m? glClearDepth(1.0f); //Configure the viewport, giving height and width glViewport(0, 0, width, height); //Clear the colour buffer glClear(GL_COLOR_BUFFER_BIT); //Initiate OpenGL for projection drawing glMatrixMode(GL_PROJECTION); //Load identity, purpose still unknown glLoadIdentity(); //Initiate viewport as perspective, give the field of view, aspect ratio (width/height), minimum distance and maximum distance gluPerspective(45.0f, (float)width / (float)height, 0.01f, 500.0f); //Initiate OpenGL for model drawing, preparation for frame rendering glMatrixMode(GL_MODELVIEW); //Load identity again (identity matrix?) glLoadIdentity(); //Set the shading model to smooth. Other options feasable, but don't look as good glShadeModel(GL_SMOOTH); //For whatever reason, we need to state how to calculate depth. Grouped under "Alpha Function" glDepthFunc(GL_LEQUAL); //Calculate perspective as "nicest"; "don't care" and "fastest" are other options glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); //Finished configuring OpenGL return; } </code></pre> <p>Here my loadTexture function (errorCode remains 0 through the entire function, and nothing is printed to stderr):</p> <pre><code>//Function to load textures from file. Needs to know the filename / relative location. //Load textures from file int loadTexture(char *filename) { GLuint returnValue = -1; SDL_Surface *image; void *raw; int width, height, bpp; Uint8 *srcPixel, *dstPixel; Uint32 truePixel; GLenum errorCode; image = IMG_Load(filename); if(!image) { fprintf(stderr, "Warning: Error loading image %s: %s\n", filename, IMG_GetError()); return -2; } if(image-&gt;format-&gt;BytesPerPixel &lt; 2) { fprintf(stderr, "Warning: %s is a bad image, not true colour\n", filename); return -3; } width = image-&gt;w; height = image-&gt;h; raw = (void *)malloc(width * height * 4); dstPixel = (Uint8 *)raw; SDL_LockSurface(image); bpp = image-&gt;format-&gt;BytesPerPixel; for(int i = height - 1; i &gt;= 0; i--) { for(int j = 0; j &lt; width; j++) { srcPixel = (Uint8 *)image-&gt;pixels + i * image-&gt;pitch + j * bpp; switch(bpp) { case 1: truePixel = *srcPixel; break; case 2: truePixel = *(Uint16 *)srcPixel; break; case 3: if(SDL_BYTEORDER == SDL_BIG_ENDIAN) truePixel = srcPixel[0] &lt;&lt; 16 | srcPixel[1] &lt;&lt; 8 | srcPixel[2]; else truePixel = srcPixel[0] | srcPixel[1] &lt;&lt; 8 | srcPixel[2] &lt;&lt; 16; break; case 4: truePixel = *(Uint32 *)srcPixel; break; default: fprintf(stderr, "Warning: image BPP of %d in image %s unuseable\n", bpp, filename); SDL_UnlockSurface(image); SDL_FreeSurface(image); free(raw); return -4; } SDL_GetRGBA(truePixel, image-&gt;format, &amp;(dstPixel[0]), &amp;(dstPixel[1]), &amp;(dstPixel[2]), &amp;(dstPixel[3])); dstPixel++; dstPixel++; dstPixel++; dstPixel++; } } SDL_UnlockSurface(image); SDL_FreeSurface(image); while(glGetError()); glGenTextures(1, &amp;returnValue); glBindTexture(GL_TEXTURE_2D, returnValue); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR/*_MIPMAP_LINEAR*/); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); //glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_TRUE); glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); glTexImage2D(GL_TEXTURE_2D, 0, 4, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, (Uint8 *)raw); errorCode = glGetError(); if(errorCode) { if(errorCode == GL_OUT_OF_MEMORY) fprintf(stderr, "Warning: Texture memory full while binding texture from image %s\n", filename); else fprintf(stderr, "OpenGL error while creating texture: %d", (int)errorCode); glDeleteTextures(1, &amp;returnValue); free(raw); return -5; } //gluBuild2DMipmaps(GL_TEXTURE_2D, 4, width, height, GL_RGBA, GL_UNSIGNED_BYTE, (Uint8 *)raw); errorCode = glGetError(); if(errorCode) { if(errorCode == GL_OUT_OF_MEMORY) fprintf(stderr, "Warning: Texture memory full while building texture from image %s\n", filename); else fprintf(stderr, "OpenGL error while creating texture: %s", (int)errorCode); glDeleteTextures(1, &amp;returnValue); free(raw); return -6; } return returnValue; } </code></pre> <p>Finally, my actual render code. Note that the return value for the loadTexture function is copied into all elements of the texture array (right, left, top, bottom, front, back (enums)).</p> <pre><code>void cube::render(void) { float xMinOffset, xMaxOffset, yMinOffset, yMaxOffset, zMinOffset, zMaxOffset; //getoffset(xMinOffset, xMaxOffset, yMinOffset, yMaxOffset, zMinOffset, zMaxOffset); xMinOffset = yMinOffset = zMinOffset = 0.0f; xMaxOffset = yMaxOffset = zMaxOffset = 1.0f; //Positive x, or right glBegin(GL_QUADS); { glColor3f(1.0f, 1.0f, 1.0f); glNormal3f(1.0f, 0.0f, 0.0f); glBindTexture(GL_TEXTURE_2D, texture[right]); glTexCoord2f(0.0f, 1.0f); glVertex3f(xMaxOffset, yMinOffset, zMinOffset); glTexCoord2f(1.0f, 1.0f); glVertex3f(xMaxOffset, yMinOffset, zMaxOffset); glTexCoord2f(1.0f, 0.0f); glVertex3f(xMaxOffset, yMaxOffset, zMaxOffset); glTexCoord2f(0.0f, 0.0f); glVertex3f(xMaxOffset, yMaxOffset, zMinOffset); } glEnd(); //Negative x, or left glBegin(GL_QUADS); { glColor3f(1.0f, 1.0f, 1.0f); glNormal3f(-1.0f, 0.0f, 0.0f); glBindTexture(GL_TEXTURE_2D, texture[left]); glTexCoord2f(0.0f, 1.0f); glVertex3f(xMinOffset, yMinOffset, zMinOffset); glTexCoord2f(1.0f, 1.0f); glVertex3f(xMinOffset, yMinOffset, zMaxOffset); glTexCoord2f(1.0f, 0.0f); glVertex3f(xMinOffset, yMaxOffset, zMaxOffset); glTexCoord2f(0.0f, 0.0f); glVertex3f(xMinOffset, yMaxOffset, zMinOffset); } glEnd(); //Positive y, or top glBegin(GL_QUADS); { glColor3f(1.0f, 1.0f, 1.0f); glNormal3f(0.0f, 1.0f, 0.0f); glBindTexture(GL_TEXTURE_2D, texture[top]); glTexCoord2f(1.0f, 1.0f); glVertex3f(xMinOffset, yMaxOffset, zMinOffset); glTexCoord2f(1.0f, 0.0f); glVertex3f(xMinOffset, yMaxOffset, zMaxOffset); glTexCoord2f(0.0f, 0.0f); glVertex3f(xMaxOffset, yMaxOffset, zMaxOffset); glTexCoord2f(0.0f, 1.0f); glVertex3f(xMaxOffset, yMaxOffset, zMinOffset); } glEnd(); //Negative y, or bottom glBegin(GL_QUADS); { glColor3f(1.0f, 1.0f, 1.0f); glNormal3f(0.0f, -1.0f, 0.0f); glBindTexture(GL_TEXTURE_2D, texture[bottom]); glTexCoord2f(1.0f, 1.0f); glVertex3f(xMinOffset, yMinOffset, zMinOffset); glTexCoord2f(1.0f, 0.0f); glVertex3f(xMinOffset, yMinOffset, zMaxOffset); glTexCoord2f(0.0f, 0.0f); glVertex3f(xMaxOffset, yMinOffset, zMaxOffset); glTexCoord2f(0.0f, 1.0f); glVertex3f(xMaxOffset, yMinOffset, zMinOffset); } glEnd(); //Positive z, or front glBegin(GL_QUADS); { glColor3f(1.0f, 1.0f, 1.0f); glNormal3f(0.0f, 0.0f, 1.0f); glBindTexture(GL_TEXTURE_2D, texture[front]); glTexCoord2f(0.0f, 1.0f); glVertex3f(xMinOffset, yMinOffset, zMaxOffset); glTexCoord2f(0.0f, 0.0f); glVertex3f(xMinOffset, yMaxOffset, zMaxOffset); glTexCoord2f(1.0f, 0.0f); glVertex3f(xMaxOffset, yMaxOffset, zMaxOffset); glTexCoord2f(1.0f, 1.0f); glVertex3f(xMaxOffset, yMinOffset, zMaxOffset); } glEnd(); //Negative z, or back glBegin(GL_QUADS); { glColor3f(1.0f, 1.0f, 1.0f); glNormal3f(0.0f, 0.0f, -1.0f); glBindTexture(GL_TEXTURE_2D, texture[back]); glTexCoord2f(1.0f, 1.0f); glVertex3f(xMinOffset, yMinOffset, zMinOffset); glTexCoord2f(1.0f, 0.0f); glVertex3f(xMinOffset, yMaxOffset, zMinOffset); glTexCoord2f(0.0f, 0.0f); glVertex3f(xMaxOffset, yMaxOffset, zMinOffset); glTexCoord2f(0.0f, 1.0f); glVertex3f(xMaxOffset, yMinOffset, zMinOffset); } glEnd(); } </code></pre> <p>And here the render function, along with some other drawing-related functions. Note that initDisplayLists() is called in initialisation.</p> <pre><code>void redraw(void) { //Still has the data from the previous frame //Clear the colour and depth buffers before rendering glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); //Load identity, purpose unknown glLoadIdentity(); //Draw horizontal crosshair glBegin(GL_LINES); { //White colour glColor3f(1.0f, 1.0f, 1.0f); //x, y, z //Vertex2f would be ideal, but doesn't appear (min view distance for perspective?) glVertex3f(-0.0001f, 0.0f, -0.01f); glVertex3f(0.0001f, 0.0f, -0.01f); } glEnd(); //Draw vertical crosshair glBegin(GL_LINES); { //Also white glColor3f(1.0f, 1.0f, 1.0f); //Again: x, y, z glVertex3f(0.0f, -0.0001f, -0.01f); glVertex3f(0.0f, 0.0001f, -0.01f); } glEnd(); //Rotate on the x axis (pitch) glRotatef(se::pl0.rX, 1.0f, 0.0f, 0.0f); //Rotate viewport on the y axis (yaw) glRotatef(se::pl0.rY, 0.0f, 1.0f, 0.0f); //Translate the world by the negative of our coordinates //Camera one way = objects the other... glTranslatef(-se::pl0.x, -se::pl0.y, -se::pl0.z); glCallList(1); //Show the screen we have been calculating, preparing the screen we were showing for drawing SDL_GL_SwapBuffers(); return; } void initDisplayLists(void) { glGenLists(1); cube block = cube(); glNewList(1, GL_COMPILE); { block.render(); } glEndList(); return; } </code></pre>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload