OpenGL纹理不显示

Posted

技术标签:

【中文标题】OpenGL纹理不显示【英文标题】:OpenGL textures not show 【发布时间】:2014-01-01 07:47:24 【问题描述】:

我的问题是纹理不起作用。我把源码放在下面。

main.cpp

#include <cstdio>
#include <cstring>
#include <cmath>
#include <windows.h>
#include <gl/gl.h>
#include <gl/glu.h>
#include <gl/glext.h>
PFNGLACTIVETEXTUREPROC glActiveTexture;
#include "config.h"
#include "camera.cpp"
#include "keyboardControl.cpp"
void *__gxx_personality_v0;

#define win_style WS_CAPTION | WS_POPUPWINDOW | WS_VISIBLE

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
void EnableOpenGL();
void DisableOpenGL();
void renderframe();
void renderframe2();
void SetDCPixelFormat(HDC hDC);
void Reset();
void InitGL();
void SetRenderMode(int mode);
void InitKeys();
void CameraMove(void*);
void CameraRot(void*);
void sMode(void* data);
void LoadTextures();

HWND hWnd;
HDC hDC;
HGLRC hRC;
config CFG;
bool getFPS = 0;
int lx, ly;
int sx, sy;
bool m = false;
static int keys1[] =  6, 'W', 'S', 'D', 'A', VK_SPACE, VK_LSHIFT, (int)&CameraMove ;
static int keys2[] =  1, 'Q', (int)&CameraRot ;
static int keys3[] =  3, '1', '2', '3', (int)&sMode ;
GLuint texture;

float pixels[] = 
    1.0f, 0.0f, 0.0f,   1.0f, 1.0f, 1.0f,
    1.0f, 1.0f, 1.0f,   1.0f, 0.0f, 0.0f
;

camera cam;
keyboardControl keys;

void LoadTextures() 
    glGenTextures(1, &texture);
    glBindTexture(GL_TEXTURE_2D, texture);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 2, 2, 0, GL_RGB, GL_FLOAT, pixels);

    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);


void sMode(void* data) 
    for(int i = 0; i < 3; i++)
    
        if( ((int*)data)[i] & 1 )
        
            SetRenderMode(i);
            return;
        
    


void CameraMove(void* data) 
    int *bPtr = (int*)data;
    double add[3] =  0, 0, 0 ;
    for(int x = 0; x < 3; x++)
    
        if(bPtr[x*2]) add[x] += 0.1f;
        if(bPtr[x*2 + 1]) add[x] -= 0.1f;
    
    cam.move(add[0], add[1], add[2]);


void CameraRot(void* data) 
    if( *((int*)data) & 1 )
    
        SetCursorPos(lx, ly);
        m = !m;
    


void renderframe2() 
    static float rot = 0.0f;

    glLoadIdentity();
    gluLookAt(cam.position[0], cam.position[1], cam.position[2], cam.lookAtPos[0], cam.lookAtPos[1], cam.lookAtPos[2], 0.0f, 0.0f, 1.0f);

    glClearColor( 0.4f, 0.4f, 0.6f, 1.0f );
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    glRotatef(rot/10.0f, 1, 1, 0);
    glBegin(GL_LINES);

    glColor3f(0.0f,1.0f,0.0f);
    glVertex3f( 0.0f, 2.0f, 0.0f);
    glVertex3f( 0.0f, -2.0f, 0.0f);
    glVertex3f( 2.0f, 0.0f, 0.0f);
    glVertex3f( -2.0f, 0.0f, 0.0f);
    glVertex3f( 0.0f, 0.0f, 2.0f);
    glVertex3f( 0.0f, 0.0f, -2.0f);

    glEnd();

    glActiveTexture(GL_TEXTURE0);
    glBindTexture( GL_TEXTURE_2D, texture );

    glBegin(GL_QUADS);
    glColor3f(0.0f,0.0f,1.0f);

    glTexCoord2d(1.0f, 0.0f);   glVertex3f( 1.0f, 1.0f,-1.0f);
    glTexCoord2d(0.0f, 0.0f);   glVertex3f(-1.0f, 1.0f,-1.0f);
    glTexCoord2d(0.0f, 1.0f);   glVertex3f(-1.0f, 1.0f, 1.0f);
    glTexCoord2d(1.0f, 1.0f);   glVertex3f( 1.0f, 1.0f, 1.0f);

    glTexCoord2d(1.0f, 0.0f);   glVertex3f( 1.0f,-1.0f, 1.0f);
    glTexCoord2d(0.0f, 0.0f);   glVertex3f(-1.0f,-1.0f, 1.0f);
    glTexCoord2d(0.0f, 1.0f);   glVertex3f(-1.0f,-1.0f,-1.0f);
    glTexCoord2d(1.0f, 1.0f);   glVertex3f( 1.0f,-1.0f,-1.0f);

    glColor3f(1.0f,1.0f,1.0f);
    glVertex3f( 1.0f, 1.0f, 1.0f);
    glVertex3f(-1.0f, 1.0f, 1.0f);
    glColor3f(0.0f,0.0f,0.0f);
    glVertex3f(-1.0f,-1.0f, 1.0f);
    glVertex3f( 1.0f,-1.0f, 1.0f);

    glColor3f(1.0f,1.0f,1.0f);
    glVertex3f( 1.0f,-1.0f,-1.0f);
    glVertex3f(-1.0f,-1.0f,-1.0f);
    glColor3f(0.0f,0.0f,0.0f);
    glVertex3f(-1.0f, 1.0f,-1.0f);
    glVertex3f( 1.0f, 1.0f,-1.0f);

    glColor3f(1.0f,1.0f,1.0f);
    glVertex3f(-1.0f, 1.0f, 1.0f);
    glVertex3f(-1.0f, 1.0f,-1.0f);
    glColor3f(0.0f,0.0f,0.0f);
    glVertex3f(-1.0f,-1.0f,-1.0f);
    glVertex3f(-1.0f,-1.0f, 1.0f);

    glColor3f(1.0f,1.0f,1.0f);
    glVertex3f( 1.0f, 1.0f,-1.0f);
    glVertex3f( 1.0f, 1.0f, 1.0f);
    glColor3f(0.0f,0.0f,0.0f);
    glVertex3f( 1.0f,-1.0f, 1.0f);
    glVertex3f( 1.0f,-1.0f,-1.0f);

    glEnd();    

    glFlush();
    SwapBuffers( hDC );
    rot += 1.0f;


int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int iCmdShow) 
    CFG.resolution[0] = 800;
    CFG.resolution[1] = 600;
    WNDCLASS wc;
    MSG msg;
    wc.style = CS_OWNDC;
    wc.lpfnWndProc = WndProc;
    wc.cbClsExtra = 0;
    wc.cbWndExtra = 0;
    wc.hInstance = hInstance;
    wc.hIcon = LoadIcon( NULL, IDI_APPLICATION );
    wc.hCursor = LoadCursor( NULL, IDC_ARROW );
    wc.hbrBackground = (HBRUSH)GetStockObject( BLACK_BRUSH );
    wc.lpszMenuName = NULL;
    wc.lpszClassName = "Window1";
    RegisterClass( &wc );
    int x = 50, y = 50;
    RECT wr =  x, y, x + CFG.resolution[0], y + CFG.resolution[1] ;

    hWnd = CreateWindow( 
        "Window1", "...", 
        win_style,
        wr.left, wr.top, wr.right-wr.left, wr.bottom-wr.top,
        NULL, NULL, hInstance, NULL );

    LARGE_INTEGER li;
    QueryPerformanceFrequency(&li);
    double PCFreq = double(li.QuadPart);
    double fc = PCFreq/64;

    cam.setup(0, -10, 0, 0, 0);

    EnableOpenGL();
    InitKeys();

    glActiveTexture = (PFNGLACTIVETEXTUREPROC) wglGetProcAddress ("glActiveTexture");

    if(glActiveTexture == NULL)
    
        printf("Critical Error 1\n");
        return 1;
    

    bool bEND = false;
    __int64 CounterStart = 0;
    __int64 CounterCur = 0;
    __int64 CounterMark = 0;
    while(!bEND)
    
        if(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
        
            if(msg.message == WM_QUIT)
            
                bEND = true;
             
            else 
            
                TranslateMessage( &msg );
                DispatchMessage( &msg );
            

         
        else 
        
            QueryPerformanceCounter((LARGE_INTEGER*)&CounterStart);
            renderframe2();
            keys.a();
            QueryPerformanceCounter((LARGE_INTEGER*)&CounterCur);

            CounterMark = CounterStart + fc;
            while(CounterCur < CounterMark)
            
                QueryPerformanceCounter((LARGE_INTEGER*)&CounterCur);
                Sleep(1);
            

            if(getFPS)
            
                getFPS = 0;
                printf("%0.2lf fps\n", (double)(1/((double)(CounterCur-CounterStart)/PCFreq)));
            
        
    
    DisableOpenGL();
    DestroyWindow(hWnd);
    return msg.wParam;

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) 
    switch(message)
    
    case WM_MOVE:
    
        int xPos = ((__int16*)&lParam)[0];
        int yPos = ((__int16*)&lParam)[1];
        RECT wr =  xPos, yPos, xPos + CFG.resolution[0], yPos + CFG.resolution[1] ;
        RECT wr2;
        memcpy(&wr2, &wr, sizeof(RECT));
        AdjustWindowRect(&wr2, win_style, false);
        lx = (CFG.resolution[0] >> 1) + wr2.left;
        ly = (CFG.resolution[1] >> 1) + wr2.top;
        sx = (CFG.resolution[0] >> 1) - wr2.right + wr.right;
        sy = (CFG.resolution[1] >> 1) - wr.top + wr2.top;
     break;
    case WM_MOUSEMOVE:
    
        if(!m) break;
        int xPos = ((__int16*)&lParam)[0];
        int yPos = ((__int16*)&lParam)[1];
        if(xPos == sx && yPos == sy) 
        
            break;
        
        if(xPos != sx || yPos != sy)
        
            int ia = (xPos - sx);
            int ib = (sy - yPos);
            double a = (ia)?(double)ia / 100:0;
            double b = (ib)?(double)ib / 100:0;
            cam.moveC(a, b);
        
        SetCursorPos(lx, ly);
     break;
    case WM_CREATE:
        return 0;
    case WM_CLOSE:
        PostQuitMessage(0);
        return 0;
    case WM_DESTROY:
        return 0;
    case WM_KEYDOWN:
        switch(wParam)
        
        case VK_ESCAPE:
        
            PostQuitMessage(0);
            return 0;
        
        return 0;
        
    default:
        return DefWindowProc( hWnd, message, wParam, lParam );
    

void Reset() 
    RECT rc;
    GetClientRect(hWnd, &rc);

    int h  = rc.bottom-rc.top;
    int w = rc.right-rc.left;

    if(!h) h=1;

    glViewport(0, 0, w, h);

    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();

    gluPerspective(45.0f, (float)w/(float)h, 1.0f, 100.0f);

    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();

;
void EnableOpenGL() 
    hDC = GetDC(hWnd);
    SetDCPixelFormat( hDC );
    hRC = wglCreateContext( hDC );
    wglMakeCurrent( hDC, hRC );
    Reset();
    InitGL();
    LoadTextures();
    SetRenderMode(2);

void DisableOpenGL() 
    glDeleteTextures(1, &texture);
    wglMakeCurrent( NULL, NULL );
    wglDeleteContext( hRC );
    ReleaseDC(hWnd, hDC);

void SetDCPixelFormat( HDC hDC ) 
    INT nPixelFormat;

    static PIXELFORMATDESCRIPTOR pfd = 
    
        sizeof(PIXELFORMATDESCRIPTOR),
        1,
        PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL |
        PFD_DOUBLEBUFFER | PFD_TYPE_RGBA,
        8,
        0, 0, 0, 0, 0, 0,
        0, 0,
        0, 0, 0, 0, 0,
        16,
        0,
        0,
        PFD_MAIN_PLANE,
        0,
        0, 0, 0
    ;
    nPixelFormat = ChoosePixelFormat(hDC, &pfd);
    SetPixelFormat(hDC, nPixelFormat, &pfd);

void InitGL() 
    glEnable(GL_DEPTH_TEST);
    glDepthFunc(GL_LEQUAL);
    glEnable(GL_CULL_FACE);
    glCullFace(GL_BACK);
    glFrontFace(GL_CCW);
    glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);

void InitKeys() 
    keys.Add(keys1);
    keys.Add(keys2);
    keys.Add(keys3);

void SetRenderMode(int mode) 
  switch (mode)
  
  case 0: glPolygonMode(GL_FRONT_AND_BACK, GL_POINT); break;
  case 1:
    
      glDisable(GL_CULL_FACE);
      glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
    ; break;
  case 2:
    
      glEnable(GL_CULL_FACE);
      glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
    ; break;
  ;
;

camera.cpp

#pragma once
#include <cstring>
#include <cmath>
#include <cstdio>

class camera

public:
    double position[3];
    double lookAtPos[3];
private:
    int r;
    double speed;
    double vRad, hRad;
public:
    camera();
    //~camera();
    void setup(double x, double y, double z, double v, double h);
    void moveC(double v, double h);
    void move(double a, double b, double c);
    void debug();
    void reset();
;

camera::camera() 
    memset(position, 0, sizeof(double)*3);
    memset(lookAtPos, 0, sizeof(double)*3);
    r = 10;
    speed = 0.5f;
    vRad = 0;
    hRad = 0;


void camera::setup(double x, double y, double z, double v, double h) 
    position[0] = x;
    position[1] = y;
    position[2] = z;
    vRad = v;
    hRad = h;
    moveC(0, 0);


void camera::move(double a, double b, double c) 
    double sv = sin(vRad), cv = cos(vRad);
    double sh = sin(hRad), ch = cos(hRad);
    if(a)
    
        position[0] += ch * sv * a;
        position[1] += ch * cv * a;
        position[2] += sh * a;
    
    if(b)
    
        double svb = sin(vRad + 1.57), cvb = cos(vRad + 1.57);
        position[0] += svb * b;
        position[1] += cvb * b;
    
    if(c)
    
        position[2] += c;
    
    reset();


void camera::moveC(double v, double h) 
    if(v)
    
        vRad += v;
        if(vRad > 6.28) vRad -= 6.28;
        if(vRad < 0) vRad += 6.28;
    
    if(h)
    
        hRad += h;
        if(hRad > 1.57) hRad = 1.57;
        if(hRad < -1.57) hRad = -1.57;
    
    reset();


void camera::reset() 
    double sv = sin(vRad), cv = cos(vRad), sh = sin(hRad), ch = cos(hRad);
    lookAtPos[0] = ch * sv * r + position[0];
    lookAtPos[1] = ch * cv * r + position[1];
    lookAtPos[2] = sh * r + position[2];

keyboardControl.cpp

#pragma once
#include <cstdlib>
#include <windows.h>

class keyboardControl 
private:
    int count;
    int **DATA;
public:
    keyboardControl();
    ~keyboardControl();
    void Add(int*);
    void a();
;

keyboardControl::keyboardControl() 
    DATA = (int**) malloc(256 * 4);
    count = 0;


keyboardControl::~keyboardControl() 
    free(DATA);


void keyboardControl::a() 
    for(int i = 0; i < count; i++)
    
        int t[DATA[i][0]];
        bool work = false;
        for(int x = 0; x < DATA[i][0]; x++)
        
            t[x] = GetAsyncKeyState(DATA[i][x + 1]);
            if(t[x]) work = true;
        
        if(work)
        
            ((void (*)(void*))DATA[i][DATA[i][0]+1])(t);
        
    


void keyboardControl::Add(int* data) 
    DATA[count++] = data;

我正在使用 MinGW 和 compile.bat

@echo off
erase run.exe
set dir1="%cd%"
cd ../../../MinGW/bin
gcc %dir1%/main.cpp -lwsock32 -lopengl32 -lGdi32 -lglu32 -o %dir1%/run.exe
cd %dir1%
set dir1=
echo =-=
run
@echo on

【问题讨论】:

以后你应该pare your example down much further。我建议使用FreeGLUT 或GLFW 以及GLEW 来最小化样板代码。 【参考方案1】:

在尝试渲染纹理几何之前,通过glEnable(GL_TEXTURE_2D) 启用纹理:

glEnable(GL_TEXTURE_2D);  // important!
glActiveTexture(GL_TEXTURE0);
glBindTexture( GL_TEXTURE_2D, texture );

glBegin(GL_QUADS);
glColor3f(0.0f,0.0f,1.0f);

glTexCoord2d(1.0f, 0.0f);   glVertex3f( 1.0f, 1.0f,-1.0f);
...

glBindTexture() 是必要的,但还不够。

【讨论】:

以上是关于OpenGL纹理不显示的主要内容,如果未能解决你的问题,请参考以下文章

OpenGL纹理不显示

BMP 纹理不显示

SDL OpenGL 纹理显示问题

如何显示带有opengl纹理的灰度图像

在 OpenGL 的全屏四边形中将 QGraphicsScene 显示为纹理

OpenGL ES总结OpenGL通过计算纹理坐标来显示一张图片