OpenGL纹理不显示

时间:2014-01-01 07:47:25

标签: c++ opengl textures

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

的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

1 个答案:

答案 0 :(得分: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);
...
仅{p> glBindTexture()是必要的,但还不够。