#include <Windows.h>
#include "glut.h"
#include "GLAUX.H"
#include <stdio.h>
GLuint texID;
void display()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glClearColor(0,0,0,0);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LESS);
glMatrixMode(GL_TEXTURE);
glLoadIdentity();
gluLookAt(10,10,10,0,0,0,0,0,1);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D,texID);
glColor3f(0.9f,0.9f,0.9f);
glBegin(GL_QUADS);
glTexCoord2f(0.f,0.f);
glVertex3f(-100.0f, 0.0f, -100.0f);
glTexCoord2f(0.f,1.f);
glVertex3f(-100.0f,0.0f,100.0f);
glTexCoord2f(1.f,1.f);
glVertex3f(100.0f,0.0f,100.0f);
glTexCoord2f(1.f,0.f);
glVertex3f(100.0f, 0.0f, -100.0f);
glEnd();
glutSwapBuffers();
}
void InitTexture()
{
glGenTextures(1,&texID);
AUX_RGBImageRec * image = auxDIBImageLoad("earth.bmp");
if(!image)
puts("image open err\n");
glBindTexture(GL_TEXTURE_2D, texID);
// glTexImage2D(GL_TEXTURE_2D, 0, 3, image->sizeX,image->sizeY,0,GL_RGB,GL_UNSIGNED_BYTE,
// image->data);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
gluBuild2DMipmaps(GL_TEXTURE_2D, 3, image->sizeX, image->sizeY, GL_RGB, GL_UNSIGNED_BYTE,image->data);
delete image->data;
delete image;
image = NULL;
}
void reshape (int w, int h) {
float ratio = w/(float)h;
glViewport(0,0,w,h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45,ratio,10,1000);
}
int main(int argc, char** argv)
{
glutInit(&argc,argv);
glutInitDisplayMode(GLUT_DOUBLE|GLUT_RGBA|GLUT_DEPTH);
glutInitWindowSize(500,500);
glutCreateWindow("3D FORTRESS");
InitTexture();
glClear(GL_COLOR_BUFFER_BIT);
glutDisplayFunc(display);
glutIdleFunc (display);
glutReshapeFunc (reshape);
glutMainLoop();
return 0;
}
i'm trying to make a simple texture mapping..
but it doesn't work at all. it just displays black screen. though It reads bmp files well...
Several things wrong with this code:
glClearColor after glClear does not have any effect (until the next time through the display function).
You are switching to the texture matrix with glMatrixMode(GL_TEXTURE); but then load a view matrix into it. If you're just getting started with OpenGL, the texture matrix is not something you should be using; this should probably be GL_MODELVIEW.
The first argument to gluBuild2DMipmaps must be GLU_TEXTURE_2D.
You're not checking the return value of gluBuild2DMipmaps.
You're not checking for any OpenGL errors. Use glGetError() to pinpoint the source of any problems.
In general, with problems like this, narrow it down by commenting out features first. Here, I'd start with drawing a coloured quad without any texture, then add the texture to it.
Related
I am following this article to render a video onto a texture using OpenGL and winforms using C++.
I have changed the code in the renderer as follows. But the glutPostRedisplay(); is not working. The same logic works well when I am creating a OpenGL window and rendering over there. But does not seem to work well in winforms.
As of what I understood is that the glutPostRedisplay is trying to refresh my main winforms window and not the OpenGL viewport. I am not sure how to Refresh my viewport.
void OpenGLForm::COpenGL::Render(System::Void)
{
//glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glEnable(GL_TEXTURE_2D);
// These are necessary if using glTexImage2D instead of gluBuild2DMipmaps
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
// Draw a textured quad
glBegin(GL_QUADS);
glTexCoord2f(0.0f, 0.0f); glVertex2f(0.0f, 0.0f);
glTexCoord2f(1.0f, 0.0f); glVertex2f(frame_width, 0.0f);
glTexCoord2f(1.0f, 1.0f); glVertex2f(frame_width, frame_height);
glTexCoord2f(0.0f, 1.0f); glVertex2f(0.0f, frame_height);
glEnd();
glFlush();
//glutSwapBuffers();
OpenGLForm::COpenGL::SwapOpenGLBuffers();
//Get data from the camera
uint32_t* buffer = new uint32_t[frame_width * frame_height * 4];
if (display_mode == DISPLAY_ARGB) {
// Pass a pointer to the texture directly into Thermal_GetImage for maximum performance
status = Thermal_GetDisplayImage(camera, buffer, (uint32_t)frame_pixels);
glTexImage2D(
GL_TEXTURE_2D,
0,
GL_RGBA8,
frame_width,
frame_height,
0,
GL_RGBA,
GL_UNSIGNED_BYTE,
buffer);
// Clean up buffer
delete[] buffer;
// Update display
glutPostRedisplay();
}
void OpenGLForm::COpenGL::SwapOpenGLBuffers(System::Void)
{
SwapBuffers(m_hDC);
}
glutPostRedisplay only works with a "glut"-window. (glutCreateWindow). You have to use a Win-API function to invalidate the client area of the window (e.g. InvalidateRect):
InvalidateRect(HWND, NULL, TRUE);
I'm working on building a basketball game in openGL, however i'm taking baby steps and dividing my work into sections. I'm currently focusing on texturing, attempting to build a house using the SOIL library.
I'm extremely new to all of this so i've probably set things up wrong but my main problem is that textures are acting as if they are clamped to edge from what i can see.
Currently the project is a singular wall meant to be textured by bricks, here's an image of the output i'm getting:
Texture Fail
Here is the source code:
#include <stdlib.h>
#include <GL/glut.h>
#include <SOIL.h>
#include <stdio.h>
float _angle = 0.0;
GLuint _textureBrick;
static void resize(int width, int height)
{
const float ar = (float) width / (float) height;
glViewport(0, 0, width, height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glFrustum(-ar, ar, -1.0, 1.0, 1.0, 100.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
void renderScene(void)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glEnable(GL_TEXTURE_2D);
// Front side brick wall
glPushMatrix();
glBindTexture(GL_TEXTURE_2D, _textureBrick);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTranslatef(0,0,-6);
glRotatef(_angle, 0.0, 1.0, 0.0);
glBegin(GL_QUADS); // Wall
glTexCoord3f(-50.0,2.0,0.1); glVertex3f(-50,0,1);
glTexCoord3f(50.0,2.0,0.1); glVertex3f(50,0,1);
glTexCoord3f(50.0,0.0,0.1); glVertex3f(50,-1.5,1);
glTexCoord3f(-50.0,0.0,0.1); glVertex3f(-50,-1.5,1);
glEnd();
glPopMatrix();
glutSwapBuffers();
}
void mySpecialFunc(int key, int x, int y){
switch (key) {
case GLUT_KEY_RIGHT:
_angle += 1;
if (_angle > 360) _angle = 0.0;
break;
case GLUT_KEY_LEFT:
_angle -= 1;
if (_angle > 360) _angle = 0.0;
break;
}
glutPostRedisplay();
}
GLuint loadTex(const char* texname)
{
GLuint texture = SOIL_load_OGL_texture
(
texname,
SOIL_LOAD_AUTO,
SOIL_CREATE_NEW_ID,
SOIL_FLAG_INVERT_Y
);
if( 0 == texture )
{
printf( "SOIL loading error: '%s'\n", SOIL_last_result() );
}
//glBindTexture(GL_TEXTURE_2D, texture);
//glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
//glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
return texture;
}
void Initialize() {
glClearColor(0.0, 0.0, 0.0, 1.0);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(-100.0, 100.0, -100.0, 100.0, -100.0, 100.0);
//_textureFloor = loadTex("C:\\Users\\Mikle\\OneDrive\\Uni work\\Second Year\\Projects\\3D-House-using-OpenGL-and-C--master\\court.png");
_textureBrick = loadTex("C:\\Users\\Mikle\\OneDrive\\Uni work\\Second Year\\Projects\\3D-House-using-OpenGL-and-C--master\\bricks.bmp");
}
int main(int argc, char **argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH);
glutInitWindowPosition(0,0);
glutInitWindowSize(600,600);
glutCreateWindow("Textured House");
glEnable(GL_DEPTH_TEST);
glutReshapeFunc(resize);
glutSpecialFunc(mySpecialFunc);
glutDisplayFunc(renderScene);
Initialize();
glutMainLoop();
return 0;
}
Any help would be appreciated, thankyou!
Michael. In order to generate mipmaps and possibly fix the texture, you should change the parameters of the soil loading function to
GLuint texture = SOIL_load_OGL_texture
(
texname,
SOIL_LOAD_AUTO,
SOIL_CREATE_NEW_ID,
SOIL_FLAG_MIPMAPS | SOIL_FLAG_INVERT_Y | SOIL_FLAG_NTSC_SAFE_RGB | SOIL_FLAG_COMPRESS_TO_DXT
);
This will automatically generate mipmaps from the OpenGL library, as you did not call afterwards to glGenerateMipmaps(). It also saves on the memory needed to store the textures. Another suggestion for the texture clamping and wrapping is to use
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
after you use the load function. Good luck with your OpenGL learning experience. I hope this helped you in some way.
EDIT:
You also shouldn't repeat the glTexParameteri every single frame. This puts excess and unnecessary strain on your (or the user's) CPU.
Hey guys I'm new in OpenGL, and I have an issue while I try to display a texture.Every texture I try to display in .png format it just gives it's color, for example if I try to display a red brick it just appears the red, only the color. The code I use is below.Where should I bind the texture or what's wrong with code? I can't aunderstand.
GLuint LoadTexture(const char * filename, int width, int height){
GLuint texture_id;
unsigned char *data;
texture_id = SOIL_load_OGL_texture(filename,
4, 0, SOIL_FLAG_POWER_OF_TWO | SOIL_FLAG_MIPMAPS | SOIL_FLAG_INVERT_Y);
if (texture_id == 0)
{
printf( "SOIL loading error: '%s'\n", SOIL_last_result() );
}
glBindTexture(GL_TEXTURE_2D, texture_id);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_DECAL);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_DECAL);
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);
}
void display()
{
glClearColor(0, 0, 0, 1);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glEnable(GL_TEXTURE_2D);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
int w = glutGet(GLUT_WINDOW_WIDTH);
int h = glutGet(GLUT_WINDOW_HEIGHT);
gluPerspective(60, w / h, 0.1, 100);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(3, 3, 3,
0, 0, 0,
0, 0, 1);
glRotatef(rotate_x, 1.0, 0.0, 0.0);
glRotatef(rotate_y, 0.0, 1.0, 0.0);
glBindTexture(GL_TEXTURE_2D, texture);
glEnable(GL_TEXTURE_2D);
mycube();
glutSwapBuffers();
}
int main(int argc, char **argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGBA | GLUT_DEPTH | GLUT_DOUBLE);
glutInitWindowSize(640, 480);
glutCreateWindow("CUBE");
texture = LoadTexture("texture.png", 256, 256);
glutDisplayFunc(display);
glutSpecialFunc(specialKeys);
glEnable(GLUT_DEPTH);
glutMainLoop();
FreeTexture(texture);
return 0;
}
I do not see the source of your LoadTexture() function. One thing that can be done is to create a structure that holds the id value that OpenGL sets to a texture when it is bound to a renderable object, its width & height in pixels, color bit depth information, and the color data, if it contains transparencies, should be wrapped or repeated, and the mipmap quality being used. I do not know what you are using to open, read and parse a png file, but within my own projects I happen to use libpng.
I have a simple OpenGL program built with GLUT that draws a few buildings, have a keyboard controlled moving camera, and I am trying to texture the ground. The animation is smooth.
The problem I have is with texturing mapping the ground. Two separate issues with two separate approaches
1) If I use glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST); then I have no
flickering when I zoom out to far away. But the issue is when I zoom out from far, it appears as a single solid color.
From far:
From close:
2) If I use, glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); then I have a lot of flickering
when I zoom out to far away as I move, almost look like a TV noise when you are out of tune.
But stationary, it looks more natural.
From far:
From close:
Questions: What would be a simple way from my existing code to get the best of both worlds? Looking natural from far, and no flickering of the texture as I move. Thank you.
Here is the relevant code:
GLuint grassTextureId;
GLfloat GROUND_PLANE_WIDTH = 1000.0f;
void Display()
{
glLoadIdentity();
camera.Update();
...
FlatGroundPlane_Draw(void);
...
glutSwapBuffers();
}
void FlatGroundPlane_Draw(void)
{
glEnable(GL_TEXTURE_2D);
glBindTexture( GL_TEXTURE_2D, grassTextureId); // call glBindTexture before glBegin
glBegin(GL_QUADS);
glNormal3f(0, 1, 0);
glTexCoord2d(0, 0);
GLdouble textCoord = GROUND_PLANE_WIDTH;
glVertex3f( -GROUND_PLANE_WIDTH, 0, -GROUND_PLANE_WIDTH);
// go beyond 1 for texture coordinate so it repeats and tiles
glTexCoord2d(0, textCoord);
glVertex3f( -GROUND_PLANE_WIDTH, 0, GROUND_PLANE_WIDTH);
glTexCoord2d(textCoord, textCoord);
glVertex3f( GROUND_PLANE_WIDTH, 0, GROUND_PLANE_WIDTH);
glTexCoord2d(textCoord, 0);
glVertex3f( GROUND_PLANE_WIDTH, 0, -GROUND_PLANE_WIDTH);
glEnd();
glDisable(GL_TEXTURE_2D);
}
void Initialise()
{
glEnable(GL_DEPTH_TEST);
glClearDepth(1.0f);
glDepthFunc(GL_LEQUAL);
glHint(GL_PERSPECTIVE_CORRECTION_HINT,GL_NICEST);
modelParser = new ModelParser();
// grass texture is 1024x1024
// from http://seamless-pixels.blogspot.ca/2012_10_01_archive.html
grassTextureId = modelParser->LoadTiledTextureFromFile("./Grass/Grass_1024.ppm");
}
void ModelParser::UploadTiledTexture(unsigned int &iTexture, const RGBImage &img)
{
glGenTextures(1, &iTexture); // create the texture
glBindTexture(GL_TEXTURE_2D, iTexture);
// Issue 1: no flickering, but appear solid color from far away
//glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
//glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
// Issue 2: flickering noise during movement but appear realistic from far away
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
// the texture would wrap over at the edges (repeat)
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, img.Width(), img.Height(), GL_RGB, GL_UNSIGNED_BYTE, img.Data());
}
int main(int argc, char** argv)
{
...
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH);
...
glutDisplayFunc(&GLUT::Display);
...
glutMainLoop();
}
This problem baffles me. I am testing some Haskell bindings to OpenGL, I create a vertex shader, a fragment shader, compile the program, and draw a textured rectangle to the screen after transforming the vertices... except the screen is blank.
When I render the rectangle flat white instead of using a sampler in the fragment shader, it works fine. When I go into gdebugger and use the option to replace all textures with a stub texture, it also works fine.
When I look at the allocated textures in gdebugger, there are no texture objects, only the default 2d texture. When I set a breakpoint on glTexImage2d, I see that it is being called, but no texture object appears in memory when I peek at it with gdebugger.
What's going on? Am I forgetting to set some environment variables? I'm quite frustrated. The kicker is that I had this problem before, and I managed to fix it then, but I forgot what the problem was. I hate myself >_>
I ported a tutorial on OpenGL to Haskell some time ago. It includes a link to a very tiny library that, among other things, helps with loading textures.
Perhaps you could compare that code with what you have to spot the differences.
I'm not a Haskell guy by any means, but try doing the simplest thing that could possibly work and check to see where you deviate from it:
#include <GL/glut.h>
double aspect_ratio = 0;
GLuint texID = 0;
unsigned int texBuf[] = {
0x00FFFFFF,
0x00FF0000,
0x0000FF00,
0x000000FF,
};
void display(void)
{
glEnable(GL_DEPTH_TEST);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(-10*aspect_ratio, 10*aspect_ratio, -10, 10, -10, 10);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glColor3ub(255,255,255);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, texID);
glScalef(8,8,8);
glTranslatef(-0.5f, -0.5f, 0.0f);
glBegin(GL_QUADS);
glTexCoord2f(0,0);
glVertex2f(0,0);
glTexCoord2f(1,0);
glVertex2f(1,0);
glTexCoord2f(1,1);
glVertex2f(1,1);
glTexCoord2f(0,1);
glVertex2f(0,1);
glEnd();
glFlush();
glFinish();
glutSwapBuffers();
}
void reshape(int w, int h)
{
aspect_ratio = (double)w / (double)h;
glViewport(0, 0, w, h);
}
void idle()
{
glutPostRedisplay();
}
int main(int argc, char **argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGBA | GLUT_DEPTH | GLUT_DOUBLE);
glutInitWindowSize(200,200);
glutCreateWindow("Aspect Ratio");
glGenTextures(1, &texID);
glBindTexture(GL_TEXTURE_2D, texID);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexImage2D(GL_TEXTURE_2D, 0, 4, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, (char*)texBuf);
glutDisplayFunc(display);
glutReshapeFunc(reshape);
glutIdleFunc(idle);
glutMainLoop();
return 0;
}